ASP.NET MVC + RSS ActionResult

ASP.NET’s new MVC framework (currently at RC2 release) makes syndicating your data ridiculously simple to implement.

A Trivial Example

For example, in a trivial blogging MVC site your ‘Home’ Controller may have a ‘Posts’ Action handler, so when you navigate to ‘https://server/home/posts’ the ‘Posts’ action handler will retrieve all blog posts (or the 5 most recent) and set them as the View’s Model data.

Also, if your ‘Posts’ Action handler accepts an int32 parameter you could view a specific blog entry by navigating to ‘https://server/home/posts/123’. In this case, the  ‘Posts’ action handler will retrieve only post number ‘123’ and will set that post as the View’s Model data.

ASP.NET MVC allows you to return the Model data retrieved by the Controller in a variety of ‘out-of-the-box’ formats, including the ASPX, JSON, Plain Text etc.

There isn’t currently an RSS/Atom ActionResult (which is what every Action Handler in a Controller must return), but its really easy to ‘roll your own’. See the steps below.

 

Implementation

1) Build your own RssResult : ActionResult

Firstly, you need to create a new class and derive from the abstract class ActionResult. I’ve called mine ‘RssResult’. Create it wherever you see fit, but I just put mine in the Controllers namespace.

The only method you need to override in your new derived class is the ‘ExecuteResult’ method. This method effectively creates the output (be it; HTML, JSON, Plain Text etc) which is to be returned to the client.

So in our overriden ‘ExecuteResult’ method, we first set the response’s content type to ‘application/rss+xml’, then pass our syndication feed to the Rss20FeedFormatter which is part of WCF’s System.ServiceModel.Syndication namespace.

This formats all our syndication feed data into RSS compliant XML which is then written to the response stream, which eventually will be returned to the calling client.

 namespace RssMvc.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.ServiceModel.Syndication;
    using System.Xml;

    public class RssResult : ActionResult
    {
        public SyndicationFeed Feed { get; set; }

        public RssResult() { }

        public RssResult(SyndicationFeed feed)
        {
            this.Feed = feed;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.ContentType = "application/rss+xml";

            Rss20FeedFormatter formatter = new Rss20FeedFormatter(this.Feed);

            using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
            {
                formatter.WriteTo(writer);
            }
        }
    }
}

 

2) Add a new Action Handler in your Controller

Next, create a new Controller Action inside your ‘Home’ controller (or whatever controller you want).

Inside the Action we will create the syndication feed and syndication items therein. (in my example, I’m creating a few dummy feed items, but in the real-world you would make a call to the Model to return this data).

Once you have created your Syndication feed and feed items (once again using the System.ServiceModel.Syndication namespace), return an instance of your new RssResult, passing your feed.

 public ActionResult Rss()
{
    List<SyndicationItem> items = new SyndicationItem[] 
    {
        new SyndicationItem("Blog 1", "Joe's 1st Blog", null),
        new SyndicationItem("Blog 1", "Joe's 1st Blog", null),
        new SyndicationItem("Blog 1", "Joe's 1st Blog", null)
    }.ToList();

    SyndicationFeed feed = new SyndicationFeed("Joe's Blog Posts", "https://blogs.msdn.com/jowardel RSS Feed",Request.Url, items);
                

    return new RssResult(feed);
}
 
3) Done! – People can subscribe to your Blogs by RSS

So now when you navigate to ‘server/home/rss’ your ‘Rss’ action is invoked inside the ‘Home’ controller, which creates the feed and passes it to the RssResult which formats it and writes it to the HttpContext’s Response stream to be rendered in your browser of choice!

Comment or contact me direct if you have any questions, suggestions etc – I’d be interested in hearing from you. Hope this helps.

image

 

Code available here: