Creating RSS feeds in ASP.NET MVC
- 📅
- 📝 592 words
- 🕙 3 minutes
- 📦 .NET
- 🏷️ ASP.NET, RSS
- 💬 5 responses
ASP.NET MVC is the technology that brought me to Microsoft and the west-coast and it’s been fun getting to grips with it these last few weeks.
Last week I needed to expose RSS feeds and checked out some examples online but was very disappointed.
If you find yourself contemplating writing code to solve technical problems rather than the specific business domain you work in you owe it to your employer and fellow developers to see what exists before churning out code to solve it.
The primary excuse (and I admit to using it myself) is “X is too bloated, I only need a subset. I can write that quicker than learn their solution.” but a quick reality check:
- Time — code always takes longer than you think
- Bloat — indicates the problem is more complex than you realize
- Growth — todays requirements will grow tomorrow
- Maintenance — fixing code outside your business domain
- Isolation — nobody coming in will know your home-grown solution
The RSS examples I found had their own ‘feed’ and ‘items’ classes and implemented flaky XML rendering by themselves or as MVC view pages.
If these people had spent a little time doing some research they would have discovered .NET’s built in SyndicatedFeed
and SyndicatedItem
class for content and two classes (Rss20FeedFormatter
and Atom10FeedFormatter
) to handle XML generation with correct encoding, formatting and optional fields.
All that is actually required is a small class to wire up these built-in classes to MVC.
using System;
using System.ServiceModel.Syndication;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml;
namespace MyApplication.Something
{
public class FeedResult : ActionResult {
public Encoding ContentEncoding { get; set; }
public string ContentType { get; set; }
private readonly SyndicationFeedFormatter feed;
public SyndicationFeedFormatter Feed{
get { return feed; }
}
public FeedResult(SyndicationFeedFormatter feed) {
this.feed = feed;
}
public override void ExecuteResult(ControllerContext context) {
if (context == null)
throw new ArgumentNullException("context");
var response = context.HttpContext.Response;
response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/rss+xml";
if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
if (feed != null) {
using (var xmlWriter = new XmlTextWriter(response.Output)) {
xmlWriter.Formatting = Formatting.Indented;
feed.WriteTo(xmlWriter);
}
}
}
}
}
In a controller that supplies RSS feed simply project your data onto SyndicationItem
s and create a SyndicationFeed
then return a FeedResult
with the FeedFormatter
of your choice.
public ActionResult NewPosts() {
var blog = data.Blogs.SingleOrDefault();
var postItems = data.Posts.Where(p => p.Blog = blog)
.OrderBy(p => p.PublishedDate)
.Take(25)
.Select(p => new SyndicationItem(p.Title, p.Content, new Uri(p.Url)));
var feed = new SyndicationFeed(blog.Title, blog.Description, new Uri(blog.Url) , postItems) {
Copyright = blog.Copyright,
Language = "en-US"
};
return new FeedResult(new Rss20FeedFormatter(feed));
}
This also has a few additional advantages:
- Unit tests can ensure the
ActionResult
is aFeedResult
- Unit tests can examine the
Feed
property to examine results without parsing XML - Switching to Atom format involved just changing the new
Rss20FeedFormatter
toAtom10FeedFormatter
[)amien
5 responses to Creating RSS feeds in ASP.NET MVC
Thanks! I used the RSS feed ActionResult in building MessianicChords.com. In particular, I used it to generate an RSS feed for user-uploaded content to the site. That feed is then consumed by IfThisThenThat, which publishes new RSS items to Twitter and Facebook. Pretty cool stuff.
Thanks again for posting this RSS ActionResult, was very helpful.
I just got a message regarding my above comment. Appears that the markup stripping in this blog has stripped out some of the code, which makes my comment appear insane!
Here’s a gist with the snippet that might make it make sense: https://gist.github.com/1027181
The issue we were having was that elements were getting HTMLEncoded by default, ruining their entire purpose.
I’ve been using a similar method for producing feeds for some time. I’ve found that you suffer if you start requiring CDATA.
While my solution isn’t quite ideal, this is the technique I use to get around the lack of CDATA support in the .NET SyndicationFeed objects.
Hi Damien, Thanks for the well written article, RSS is really the glue that holds a lot of services together, leveraging it is well worth while.
On a side note, I was very happy to see your code using the “Envy Code R” font, I’ve switched to that recently and haven’t looked back :)
-Jarrod
That code makes me happy. I can’t define good code, but I know it when I see it. Simple, extensible, testable, re-uses pre existing artwork that’s baked into the framework, it ticks a whole lot of boxes. Nice work Mr Guard.