Building an Application with Blazor Bootstrap, Part 2

Published by Mika Berglund on

RSS viewer with Blazor Bootstrap

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.

  1. Part 1 – Building the navigation
  2. Part 2 – This article
  3. Part 3 – Using the Carousel component loop through items in an RSS feed

In this part, I will use the Card and 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

I thought that it would be an interesting task to put content on the demo application using an existing source. I chose the RSS feed of this blog that you are reading. The first thing that I needed to take care of was to read the contents of the RSS feed. That’s easy, I thought. Just kick off an HTTP request, and parse the resulting XML document. But, what’s pretty easy to forget when writing C# code for your Blazor Webassembly application is that it actually runs purely client-side. As such, it is also subject to the same restrictions that any JavaScript running in the browser is. There are also subtle differences in how many of the classes work, probably because the runtime is still in preview.

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.

Caching Items

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.

Summary

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!


2 Comments

Kal · July 6, 2020 at 08:48

Using your site as a sample site seems like a really good idea. Unfortunately the demo site doesn’t load and the github version is obsolete.

    Mika Berglund · July 6, 2020 at 11:51

    Hi, and thanks for pointing that out!

    After the acticle was originally published, I renamed the library and moved it to another location on GitHub. Everything else is still valid. I updated the article with an update at the beginning. I also went through the links and updated them to point to the correct resources.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *