Today we'll look at how I've built my own RSS feed in ASP.NET 3.5 using Linq2SQL.
Before we dive into that, I would like to announce that my articles are now fed through this RSS feed to www.codeproject.com. The latest of my articles (at least most of them) are now available here too. I would like to thank Sean Ewington from CodeProject for working with me and supporting me, so that I could achieve this bigger audience.
Now, back to business. As you may remember from part 1 of this series, the first goal for me was to customize my RSS feed, so I could add categories to my feed without messing up my navigation. I also outlined the phases I would go through to get to my new and improved blog and after leaving you in part 2, I reached step three which means I now have my content up and running in a database on the new platform and it gets updated through RSS from the Blogger.com platform.
I've now used the code I wrote for part 2 as a starting point for building the new RSS feed. As I had a great experience with the SyndicationFeed
class for parsing a feed, I figured I might as well use it to publish a feed as well. The general steps needed to get the feed published are these:
- Setup a
SyndicationFeed
object with some general information like title, author, etc. - Load the articles from the database and convert them into feed items
- Publish the feed
The first step actually did take some work as I wanted a lot of things to be configurable through my web.config and also it takes some extra code to set most of the properties. To help me out with loading these settings, I've built a SyndicationSettings
class which holds the constants for the config key names and accesses the ConfigurationManager
to get the actual values. I've made it a static
class, so it is as easy to use as possible.
Setting up the feed is done in the SetupFeed
method:
private static SyndicationFeed SetupFeed()
{
SyndicationFeed feed = new SyndicationFeed();
SyndicationPerson person =
new SyndicationPerson(SyndicationSettings.SyndicationPersonEmail,
SyndicationSettings.SyndicationPersonName, SyndicationSettings.SyndicationPersonUrl);
feed.Authors.Add(person);
feed.Contributors.Add(person);
feed.Categories.Add(new SyndicationCategory("CodeProject"));
feed.Copyright = new TextSyndicationContent(SyndicationSettings.Copyright,
TextSyndicationContentKind.Plaintext);
feed.Description = new TextSyndicationContent(SyndicationSettings.Description);
feed.Generator = GeneratorName;
feed.Id = SyndicationSettings.FeedId;
feed.Links.Add(new SyndicationLink(new Uri(SyndicationSettings.HomePageLink)));
feed.Title = new TextSyndicationContent(SyndicationSettings.FeedTitle);
return feed;
}
As you can see, I've created a SyndicationPerson
object to be reused both as the author and a contributor.
The next step is to load the articles from the database and convert them into SyndicationItem
instances. First I needed to get them from the database, for which I expanded the functionality of the StorageConnection
class I wrote in part 2. The basics are pretty straight forward, but as I was still fairly new to Linq2Sql, I struggled a bit with getting the categories to load with the data automatically. Here is the GetArticles
method from the StorageConnection
:
public static List<Article> GetArticles(bool loadCategories, int maxNumberOfArticles)
{
List<Article> articles = new List<Article>();
DataLoadOptions dataLoadOptions = new DataLoadOptions();
if (loadCategories)
{
dataLoadOptions.LoadWith<Article>(article => article.ArticleCategories);
dataLoadOptions.LoadWith<ArticleCategory>(articleCategory => articleCategory.Category);
}
using (Developers42_DataClassesDataContext context = new
Developers42_DataClassesDataContext())
{
context.LoadOptions = dataLoadOptions;
articles = context.Articles.OrderByDescending(article => article.PublicationDate).Take(
maxNumberOfArticles).ToList();
}
return articles;
}
I've used the LoadOptions
property to let the Linq2Sql framework know I want to include both the ArticleCategory
and the Article
entities while loading the articles. Furthermore, I used the OrderByDescending
method to specify that I want the articles on PublicationDate
and I used the Take
method to specify that I only want to load up to 25 articles at a time.
Converting the Article
objects into SyndicationItem
objects is as simple as calling the constructor including most of the properties and then adding the categories.
As the final step, all that needs to be done is to publish the result to the client. To do this, we need to first clear the existing response buffer to make sure we don't send anything already in the template. Next we can simply create an XmlWriter
that has the response stream as the underlying stream and call the SaveToRss20
method on the SyndicationFeed
with the XmlWriter
as a parameter. This is how the code looks:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
XmlWriter writer = XmlWriter.Create(Page.Response.OutputStream, settings);
Page.Response.ClearContent();
feed.SaveAsRss20(writer);
writer.Flush();
As you may have noticed, building your own RSS feed is easy when using the SyndicationFeed
class. To help you even further, I've included a link to the source here. It also includes the code from part 2 for parsing an RSS feed.
I hope this post was useful to you. Next time we'll look at parts of the new version of the Developers 42 blog.