Edit July 2020: Links in this article point to the old repository and wiki where I used to work on the Blazor Bootstrap library. In January 2020 I renamed and moved the library to github.com/Blazorade/Blazorade-Bootstrap. Everything written in this article still applies, but the location of the source code and documentation has changed.
This is the second article in a series of articles that cover different aspects of application development with Blazor Bootstrap.
- Part 1 – Building the navigation
- Part 2 – This article
- Part 3 – Using the Carousel component loop through items in an RSS feed
In this part, I will use the
CardGroup components to create a roll-up from the RSS feed of this blog. The source code for this demo application is available on GitHub. Please note that the application is a Blazor Webassembly application, so it probably won’t work on Internet Explorer for instance. Remember also that Blazor Webassembly is still in preview.
Reading the RSS Feed
One such difference that I noticed was how the
HttpClient class works. Normally with server-side software, the strong recommendation is that you don’t create a new
HttpClient instance whenever you need one. Instead, you should use the
HttpClientFactory to avoid running out of sockets on the server.
So I created an
HttpClient instance with
HttpClientFactory, and fired off a
GET request. That resulted in the following error message.
System.NotImplementedException: Cannot invoke method because it was wiped. See stack trace for details.
There’s a lot on this on the Internet, so I just put in this link to a lot of matching search results. To make a long story short, when running in Blazor Webassembly, you should in fact create a new
HttpClient instance when you need one. That’s a bit different than what we’ve learned when writing server applications running in Azure. Creating an
HttpClient instance directly solved the problem.
Reading the RSS feed was not solved just yet, though. As I mentioned above, it is very easy to forget that you are running your C# code on the client. This means that CORS requirements have to be met before the browser agrees to fulfill the request. I wrote about that in my previous article. Basically, you just have to enable CORS on the site you are sending the requests to. With this, I was able to get the HTTP requests to succeed and download the RSS feed.
Reading Blog Article Metadata
But I also wanted to show the image associated with each article. The
Card component supports images very nicely, so I wanted to make use of that too. The article image is not included in RSS feed. That’s why I ended up downloading the HTML for each article in the feed, and parse the meta data specified on each article. At the same time, I also decided to make use of a few other meta tags, as I had them parsed and available. The ones I use are shown below.
<meta name="description" content="..." /> <meta property="og:image" content="..." /> <meta property="article:section" content="..." /> <meta property="article:tag" content="..." />
The description is included also in the RSS feed, but at least with WordPress, the content of that meta tag is HTML, and I wanted to have it in plain text. It’s easier to put it on a
Card, when it’s plain text.
Building the UI
OK, so now I have the data that I want to show in the UI, and it’s time to start building it. I’ve split up the UI logic into two files; The markup in
RssCards.razor and the code to support the UI in
RssCards.razor.cs. I could have put all of the code in
RssCards.razor, and it would have worked exactly the same. It’s just my personal preference to try and keep the markup as clean and compact as possible. I still remember those “spaghetti nightmares” from the classic ASP era.
There’s one thing I’d like to point out in the code-behind file. That’s the
OnParametersSetAsync() method. In that method, I’ve implemented a simple caching mechanism, that keeps the feed items in the browser’s session storage for one hour. This is in order to improve the loading time by not having to go all the way to the site every time you want to get items. For that, I’m using the
Blazored.SessionStorage Nuget package. If you want to have a look at the source code for that package, you’ll find it on GitHub.
The rest of the code-behind code file is pretty straight forward. There’s one parameter for setting the feed URL, and one private property for holding the items to display in the UI.
The UI Markup
RssCards.razor is pretty simple too. If no Items collection is available, we’re assuming that the items are being loaded. In that case, we’ll show a loading indicator. That’s one of the Bootstrap components I haven’t implemented in Blazor Bootstrap yet, so I use standard Bootstrap markup. The
Spinner component will be included in the first release scheduled for 2020/Q1 though.
To show the items loaded from the RSS feed, I use a
CardGroup component with the type of
Deck. A card group will adjust the size of the cards to be the same, and also align the footers on each card. In a deck, there will be a margin between each card in the group. Read more about card decks on the Bootstrap documentation.
For each item displayed, I use a
Card with some modifications. First, I’m setting a fixed height on the image. I’m also scaling the image so that it completely fills the area for the image. That’s something I might implement in the
Card component directly later.
I’ve also customized the title by adding the publish date of the item above the actual title with a smaller font. Here’s another thing to note. Since you are running in the client,
DateTime.ToString("d") will format the date according to the browser settings, so there’s no need to do any other kind of date formatting.
In the text area of the card, I’m adding the tags specified on the item as pill badges above the description of the item. Finally, in the footer I have a link to the article behind the item.
To run the demo application, you probably have to change the feed to something where you can control the CORS settings on. Since I moved my blog to a commercial provider, it seems that any CORS setting changes I make are reset after some time.
The first time you load the front page, it will take some time to get the items. But when you navigate to another page and then back to the front page, the items will be shown immediately. That’s because the’re kept in the session storage for one hour.
I will be creating more content on the demo application and write articles about that work, so stay tuned!