Instructor-led online courses : ASP.NET Core 2.2, Angular 7, and ASP.NET Core Design Patterns. Read more...

Aggregate Multiple RSS Feeds in ASP.NET Core

Public websites and blogs often expose their content in the form of RSS or Atom feeds. If you are developing ASP.NET Core website you can either use System.Xml classes to generate the RSS feed yourself or resort to System.ServiceModel.Syndication classes to generate RSS / Atom feeds. At times you also need to aggregate multiple feeds into a new feed. This is a case when you have a network of websites and you wish to expose content from all of them into a single feed. You might also have many feeds for individual content categories and want the end user to either get individual feeds or a combined feed. To that end this article discusses how to aggregate multiple RSS feeds in ASP.NET Core.

Begin by creating a new ASP.NET Core website and configure it to use MVC and default routing. In order to combine RSS feeds from multiple sources you need to read  them first and then generate a new feed. To accomplish this task we will use System.ServiceModel.Syndication NuGet package. So, using the Manager NuGet packages option install System.ServiceModel.Syndication as shown below :

Ok. Now open the HomeController and import the following namespaces :

using System.Xml;
using System.ServiceModel.Syndication;

Then add an action method called Rss() as shown below:

public void Rss()
{
  ...
  ...
}

Notice that the Rss() action returns void instead of IActionResult. This is because we will be writing the feed content directly on the response stream.

Next, declare a string array inside the Rss() action to hold a list of RSS feed URLs. This is shown below:

string[] feeds = new string[] {
  "http://example.com/feed1",
  "http://example.com/feed2"
};

Also declare a List of SyndicationItem objects to hold the combined RSS feed items.

 List<SyndicationItem> finalItems = new List<SyndicationItem>();

Now, we will iterate through the feeds array and fetch RSS feed items from each feed one-by-one.

foreach (string feed in feeds)
{
    XmlReader reader = XmlReader.Create(feed);
    Rss20FeedFormatter formatter = new Rss20FeedFormatter();
    formatter.ReadFrom(reader);
    reader.Close();
    finalItems.AddRange(formatter.Feed.Items);
}

As you can see, we create an XmlReader object based on a feed URL. This is done using the Create() method of XmlReader class. Then we create Rss20FeedFormatter object and load the RSS feed into it. This is done using the ReadFrom() method. The ReadFrom() method accepts an XmlReader object and pulls the RSS feed into the formatter. The XmlReader is then closed and the feed items are added to the finalItems list using the AddRange()method.

The above code will aggregate multiple RSS feed items into a single list, but these items may not be in the descending order of publication date. So, we need to sort the finalItems list based on the PublishDate property if FeedItem objects.

finalItems.Sort(CompareDates);

Here, CompareDates() is a private method supplied to the Sort() method and is shown below:

private int CompareDates(SyndicationItem x, SyndicationItem y)
{
    return y.PublishDate.CompareTo(x.PublishDate);
}

Ok. So far so good. Now we have all the RSS feed items into a single place, that too in proper order. We can now form the final feed using SyndicationFeed class. This is done as shown below:

SyndicationFeed finalFeed = new SyndicationFeed();
finalFeed.Title = new TextSyndicationContent("My RSS Feed");
finalFeed.Copyright = new TextSyndicationContent
("Copyright (C) 2018. All rights reserved.");
finalFeed.Description = new TextSyndicationContent
("RSS Feed Generated .NET Syndication Classes");
finalFeed.Generator = "My RSS Feed Generator";
finalFeed.Items = finalItems;

The above code creates an SyndicationFeed object. It then sets various properties of the final feed such as Title, Copyright, Descriptions, and Generator. Moreover, it sets the Items collection to the finalItems so that the aggregated list of items becomes the part of the new feed.

Our aggregated RSS feed is now ready. We can send it back to the client using the following code:

Response.ContentType = "text/xml";
XmlWriter writer = XmlWriter.Create(Response.Body);
Rss20FeedFormatter finalFormatter = 
new Rss20FeedFormatter(finalFeed);
finalFormatter.WriteTo(writer);
writer.Close();
Response.Body.Flush();

In order to write the aggregated feed onto the response stream, we set the ContentType to text/xml since an RSS feed is an XML document. We then create an XmlWriter based on the Response's Body property (which is a Stream). A new Rss20FeedFormatter object is then created by passing the XmlWriter.

The WriteTo() methof of Rss20FeedFormatter class writes the RSS feed onto the response stream. We then close the XmlWriter and Flush() the response stream.

If you run the application you should see RSS feed in the browser. The following figure shows a sample run of the application.

That's it for now! Keep coding!!


Bipin Joshi is a software consultant, trainer, author, yoga mentor, and spiritual guide having 24+ years of experience in software development, consulting, and training. He conducts instructor-led online training courses in ASP.NET Core, ASP.NET MVC, and Design Patterns for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get article updates : Facebook  Twitter  LinkedIn

Posted On : 17 December 2018


Tags : ASP.NET ASP.NET Core MVC .NET Framework C# Visual Studio


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.

  

Receive Weekly Updates