pr0g33k

Creating a RSS Feed Using a Custom ActionResult

When it came time to create an RSS feed for this blog, I almost fell back on what I'd done in the past - create a generic handler to output the XML. Since I'm doing everything I can to use MVC these days, I wanted to find the "MVC way" to output an RSS feed. I figured there was a way to use a controller but when I used Bing to Google it (special thanks to Scott Hanselman for that joke), all I could find was people using a controller to pass data to a view and then run a loop in the markup to assemble the XML. That just seemed gross to me. I wanted more of a C# code approach - especially since the good folks at Microsoft went to the trouble of creating the System.ServiceModel.Syndication namespace. Finally I stumbled across a forum post that referenced a video of Scott Hanselman using System.Web.Mvc.FileResult as a base to create a custom ActionResult. Bingo! The RssController looks like this:

public class RssController : Controller
{
    public ActionResult Index()
    {
        return new RssResult();
    }
}
    

That's just sexy. The RssResult looks like this:

public class RssResult : FileResult
{
    public RssResult() : base("application/rss+xml") { }

    protected override void WriteFile(HttpResponseBase response)
    {
        List<SyndicationItem> syndicationItems = new List<SyndicationItem>();
        List<Blog> blogs = BlogManager.Instance.GetEntitiesForRss(HttpContext.Current.Request.Url.Host, 1, 25);
        String url;

        foreach (Blog blog in blogs)
        {
            url = String.Format("http://www.pr0g33k.com/blog/{0}/{1}", blog.Id, blog.Title.ToSlug());
            syndicationItems.Add(new SyndicationItem(blog.Title, String.Format("{0}<p><a href=\"{1}\">Read more...</a></p>", blog.Body, url), new Uri(url), url, blog.CreateDate.ToUniversalTime())
            {
                PublishDate = blog.CreateDate.ToUniversalTime()
            });
        }

        SyndicationFeed syndicationFeed = new SyndicationFeed("pr0g33k's Blog", "pr0g33k (Robert Gaut) is a Dallas-area Microsoft .NET developer who specializes in C#, MVC 4, WPF, Silverlight, WCF, HTML5, jQuery/JavaScript, and code generation. pr0g33k's blog covers those technologies as well as other technologies that he finds cool and interesting.", new Uri("http://www.pr0g33k.com/rss"), syndicationItems);
        syndicationFeed.Authors.Add(new SyndicationPerson("pr0g33k@hotmail.com", "Robert Gaut", "http://www.pr0g33k.com"));
        SyndicationFeedFormatter feedFormatter = new Rss20FeedFormatter(syndicationFeed);

        using (XmlWriter xmlWriter = XmlWriter.Create(response.Output))
        {
            feedFormatter.WriteTo(xmlWriter);
        }
    }
}
    

The BlogManager.Instance.GetEntitiesForRss() function is part of my code-generated DAL. Everything else is pretty standard. You can see the output here. This is also very testable using automated testing if you're into that sort of thing - much moreso than generating the RSS/XML in a view.

Posted on 5/14/2013 at 08:05 PM , Edited on 5/24/2013 at 06:05 PM
Tags: C#MVC

Comments:

  1. Dan Beaulieu

    dude, you flippin rock. I've tried about 10 different examples, yours worked with very little effort.
    Thanks!
  2. pr0g33k

    Thanks! Glad you like it. Yeah, custom ActionResults are pretty slick. I've since converted it to use Entity Framework but everything else is the same. Thanks for dropping by!
Leave a comment
  1. CAPTCHA