Generate Rss and Atom Feeds using Asp.Net MVC – part 2

In the previous post Generating Rss Feeds using Asp.Net MVC – part 1, we looked into how to generate Rss Feed using an Asp.Net MVC application. In this short article, we will see how can we generate variable types of Feed by just modifying couple of lines of code.

We need to determine what Feed Format request is coming in from the customer. I have modified the route registrar in global.aspx to accept a default and a custom feed request as well.

routes.MapRoute(
                "Feed", // Route name
                "{controller}/{type}", // URL with parameters
                new { controller = "Feed", action = "Index", type = UrlParameter.Optional } // Parameter defaults
            );

We will just need to mention the Feed or a combination of Feed and Type. Similar urls extension will work

// default, which is Rss
http://codingphobia.com/Feed

// for Atom Feed
http://codingphobia.com/Feed/Atom

We will need to shift some of the ExecuteResult logic out into methods and call appropriate one depending upon request.


        //For Atom Feed request
        private static void WriteToAtomFormatter(ControllerContext context, SyndicationFeed Feed)
        {
            Atom10FeedFormatter atomFormatter = new Atom10FeedFormatter(Feed);
            using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
            {
                atomFormatter.WriteTo(writer);
            }
        }

        //For Default Rss Feed request
        private static void WriteToRssFormatter(ControllerContext context, SyndicationFeed Feed)
        {
            Rss20FeedFormatter rssFormatter = new Rss20FeedFormatter(Feed);
            using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
            {
                rssFormatter.WriteTo(writer);
            }
        }

We need to modify our ExecuteResult Method like as follows

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

            // check if the request is for Atom Feed
            if (context.HttpContext.Request.Url.OriginalString.Contains("Atom"))
                WriteToAtomFormatter(context, Feed);
            else
                WriteToRssFormatter(context, Feed);
        }

And this is all the work. Just with 7 lines of code and bit of modification, we may now generate Atom or Rss feed as per client request. We can also add logic for any Feed Format. Only important thing to work over is the returning ActionResult.

Advertisements

Generating Rss Feeds using Asp.Net MVC – part 1

This is a two part series in which I would explain a bit how can we generate Syndication feed using Asp.Net MVC and Syndication framework. first part will look into how to implement basic structure and second part will explain about how can we use a single line check and generate any type of feed, like Atom, Rss or another as per requirement.

I will start with a custom ActionResult named as FeedActionResult

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

We need our FeedActionResult to return our feed as an Object of Type ActionResult. Here is how we do this.

        public ActionResult GetFeed()
        {
            SyndicationFeed feed =
                   new SyndicationFeed("codingphobia.com Feed",
                                       "This is a feed from codingphobia.com",
                                       new Uri("http://codingphobia.com/feed/"),
                                       "somefeedID",
                                       DateTime.Now);
            SyndicationItem item1 =
                new SyndicationItem("Linq To XML: Generate Types with Nested Types using C#",
                                   "This is the content for Test item2",
                                    new Uri("http://codingphobia.com/2010/03/12/linq-to-xml-generate-types-with-nested-types-using-c/"),
                                   "TestItemID",
                                   DateTime.Now);

            List<SyndicationItem> items = new List<SyndicationItem>();

            items.Add(item1);
            feed.Items = items;

            return new FeedActionResult() { Feed = feed };
        }

As ActionResult is an abstract class, we need to provide implementation for the ExecuteResult method which is as follows

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

            Rss20FeedFormatter rssFormatter = new Rss20FeedFormatter(Feed);
            using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
            {
                 rssFormatter.WriteTo(writer);
            }
        }

Now we can call FeedActionResult.GetFeed() from our Controller, dedicated for processing requests for Feeds. Here is how we do this

    public class FeedController : Controller
    {      
        // GET: /Feed/
        public ActionResult Index(string format)
        {
            return new FeedActionResult().GetFeed();
        }
    }

I have used action method Index(string format) with as string parameter here. This will help us to receive requests, for both Atom and Rss based Formats. We will look into this in later Post.

Following is the route settings in the global.asx file

routes.MapRoute(
                "Feed", // Route name
                "{controller}/{action}/{type}", // URL with parameters
                new { controller = "Feed", action = "Index", type = UrlParameter.Optional } 
            );

How to Generate an AtomFeed using Argotic Framework. Part 4

Argotic Framework provides several classes which are great for the manipulation of a feed resource. AtomFeed class could helps us retrive all the required bits about particular Atom based feed resource and latest content it holds. On the other hand we can use the same class to generate a feed for our on line resources as well. Below is sample program which demonstrates an AtomFeed Object in action.

// create a new AtomFeed Object
                AtomFeed feed = new AtomFeed();

                // Set the title for the feed
                feed.Title = new AtomTextConstruct("codingphobia.com articles");

                // set the language you Feed is published in
                feed.Language = new System.Globalization.CultureInfo("en-gb");

                // set the description for the Feed / Feed resource
                feed.Subtitle = new AtomTextConstruct("Latest Content from codingphobia.com");

                // Set the categories under the Feed / content is published
                feed.Categories.Add(new AtomCategory("AtomFeed"));
                feed.Categories.Add(new AtomCategory("cSharp"));
                feed.Categories.Add(new AtomCategory("SyndicationFeed"));

                // Set the information about the feed Generator Engine
                feed.Generator = new AtomGenerator("WordPress3.0");

                // Add the List of Post / Articles / content links 
                // and information to the Feed Object

                // Adding  Article 1
                AtomEntry atomEntry = new AtomEntry();
                atomEntry.BaseUri = new Uri("http://codingphobia.com/category/c/page/2/");
                atomEntry.Categories.Add(new AtomCategory("Fameworks"));
                atomEntry.Title = 
                    new AtomTextConstruct("Really simple syndication -RSS with .Net. Intro");
                atomEntry.Content = new AtomContent("Some content", UTF32Encoding.Unicode.BodyName);
                atomEntry.PublishedOn = DateTime.Now;
                feed.AddEntry(atomEntry);

                // Adding  Article 2
                atomEntry.BaseUri = new Uri("http://codingphobia.com/category/c/page/1/");
                atomEntry.Categories.Add(new AtomCategory("FeedTypes"));
                atomEntry.Title = new AtomTextConstruct("RSS with .Net. Part1");
                atomEntry.Content = new AtomContent("Some more content", UTF32Encoding.Unicode.BodyName);
                atomEntry.PublishedOn = DateTime.Now;
                feed.AddEntry(atomEntry);

                // Set the url for the Icon for your Feed
                // Displayed on the side of the feed page
                feed.Icon = new AtomIcon(new Uri("http://codingphobia.com/officialImage"));

                // Set the url for the logo for your Feed
                // Displayed on the side of the feed page
                feed.Logo = new AtomLogo(new Uri("http://codingphobia.com/officialLogo"));

                // Set the right for feed consumption 
                feed.Rights = new AtomTextConstruct("CC");     

How to consume an Atom feed using Argotic Framework. (Part 2)

Argotic Framework provides several classes which are great for the manipulation of a feed resource. AtomFeed class could helps us retrive all the required bits about particular Atom based feed resource and latest content it holds, once the feed is loaded. Below is sample program which demonstrates a AtomFeed Object in action.

            /// Loads the feed.           
            /// <param name="urlToLoad">The URL to load.</param>
            AtomFeed feed = AtomFeed.Create(new Uri(urlToLoad));

            // get the url for Feed(same as used for load).  
            string feedUrl;
            if (feed.BaseUri != null)
            {
                feedUrl = feed.BaseUri.AbsolutePath;
            }

            // get the Title for the feed
            string feedTitle;
            if (feed.Title != null)
            {
                feedTitle = feed.Title.Content;
            }

            // get the description for the feed
            string feedDescription;
            if (feed.Subtitle != null && !feed.Subtitle.Equals(""))
            {
                feedDescription = feed.Subtitle.Content;
            }

            // get the icon for the source of the feed
            string feedIconUrl;
            if (feed.Icon != null)
            {
                feedIconUrl = feed.Icon.Uri.AbsoluteUri;
            }

            // get the format isn which feed id published
            string feedFormat;
            if (!feed.Format.Equals(""))
            {
                feedFormat = feed.Format.ToString();
            }

            // get the logog used by the publisher
            string feedLogo;
            if (feed.Logo != null)
            {
                feedLogo = feed.Logo.Uri.AbsoluteUri;
            }

            // get the rights as announced by the publisher of the feed
            string feedRights;
            if (feed.Rights != null)
            {
                feedRights = feed.Rights.Content;
            }

            // get the version of the Feed like 1.0 / 2.0 / 3.0 
            string FeedVersion;
            if (feed.Version != null)
            {
                FeedVersion = feed.Version.ToString();
            }

            // get the categories under which feed was published
            Collection<AtomCategory> categoryList;
            if (feed.Categories.Count > 0)
            {
                categoryList = feed.Categories; ;
            }

            // get the list of entries(posts / articles / whatever) from
            // this source
            if (feed.Entries != null)
            {
                List<AtomEntry> entries = feed.Entries.ToList<AtomEntry>();
            }