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.
Code available here:
Comments
Anonymous
March 11, 2009
PingBack from http://www.anith.com/?p=17718Anonymous
March 12, 2009
I just blogged about basically the exact same thing, except using Argotic (a much more complete feed framework than the built-in one) http://john-sheehan.com/blog/using-argotic-syndication-framework-with-aspnet-mvc/ Amazing how similar our code is for the RssResultAnonymous
April 05, 2009
Cross Domain Ajax Calls ASP.NET MVCAnonymous
May 30, 2009
转载地址:http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-kn...Anonymous
May 31, 2009
ScottGu在其最新的博文中推荐了SimoneChiaretta的文章13ASP.NETMVCextensibilitypointsyouhavetoknow,该文章为我们简单介绍...Anonymous
May 31, 2009
ScottGu在其最新的博文中推荐了SimoneChiaretta的文章13ASP.NETMVCextensibilitypointsyouhavetoknow,该文章为我们简单介绍...Anonymous
March 23, 2011
Loved the article, and also read some others, but I'm having a recurring problem in vb. (Event went and tried to figure out the namespace at Microsoft.) The first item gives the error in Visual Studio 2008 of (Microsoft.VisualBasic.Collection has no type parameters and so cannot have type arguments). The second (Type 'List' is not defined). Any help appreciated. Dim feedItems As Collection(Of SyndicationItem) = New Collection(Of SyndicationItem)() Dim feedItems As New List(Of SyndicationItem)()Anonymous
September 29, 2011
It's 0:07, i had to finish a MVC project for tomorrow and missed RSS, didn't know how to do; i've used your code and it's running great. Thanks for saving my night !!!Anonymous
November 16, 2011
Good starting point for novice userAnonymous
March 20, 2012
Hello, the output of this code was this not like ur snapshot could i know why thank u for ur help <?xml version="1.0" encoding="utf-8"?><rss xmlns:a10="www.w3.org/.../Atom" version="2.0"><channel><link>http://localhost:2903/home/rss</link><description>http://blogs.msdn.com/jowardel RSS Feed</description><item><title>Blog 1</title><description>Joe's 1st Blog</description></item><item><title>Blog 2</title><description>Joe's 2nd Blog</description></item><item><title>Blog 3</title><description>Joe's 3rd Blog</description></item></channel></rss>