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.

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 } 
            );

Difference between Page.IsPostBack and Page.IsCallBack

Page.IsCallBack

It is getting a value indicating whether the page request is the result of a call back. Its a special postback, so a round-trip always occurs; however, unlike the classic postback, the script callback doesn’t redraw the whole page. ViewState is not updated during a callback, it is for postback. IsPostBack is true when a method in the code behind posts a page

Page.IsPostBack

Checks whether the Page is accessing the server for the first time or not. Unlike the IsCallBack, the ViewState is updated. IsPostBack is true when an AJax call, calls back a the page.

How to make a callback?

In the client side JavaScript code, if GetCallbackEventReference() method is reference, then when the JavaScript code is executed, a channel to the server is opened and an HTTP request is sent to the remote ASP.NET page.[1]

references: [1] Script Callback

Linq To XML: Generate Types with Nested Types using C#

In this article, we will have look at how can we generate Types with subtypes using Linq To XML

Suppose we have an XML file which holds information about Cars as their Model Name, Transmission details, Engine Details and some other information, like follows

<?xml version="1.0" encoding="utf-8" ?> 
<Cars>
 <Car Name = "Golf">
    <Transmission Type="Manual" Gears="5" />
    <Engine Type="diesel" Power="2000" />
 </Car>
 <Car Name = "Mazda">
    <Transmission Type="Automatic" Gears="4" />
    <Engine Type="Patrol" Power="2000" />
 </Car>
</Cars>

Now we have class named Car as Follows

    class Car
    {
        // struct Transmission
        public Transmission Transmission { get; set; }
        // struct Engine
        public Engine Engine { get; set; }
    }

Class car has two properties which are structs, Transmission and Engine

    struct Engine
    {
        // Type of Engine
        public string Type
        { get; set; }

        // Power of Engine
        public int Power
        { get; set; }
    }
    struct Transmission
    {
        // Type of Transmission
        public string Type
        { get; set; }

        // Type of Transmission
        public int Gears
        { get; set; }

        public override string ToString()
        { return Type + " " + Gears; }
    }

This is how we can parse the above XML document using XElement and Linq To XML and generate the required classes

                 // Load Document using XElement
                 XElement elements = XElement.Load("XMLFile.xml");

                 // using Linq To Xml parse and load Objects
                 List<Car> CarsList =
                 (from e in elements.Descendants("Car")
                 // get new Car object
                 select new Car
                 {
                     // get Name for the Car
                     Name = e.Attribute("Name").Value,

                     // get Transmission details for the Car
                     Transmission = new Transmission()
                     {
                         Type = e.Element("Transmission").Attribute("Type").Value,
                         Gears = Convert.ToInt32(e.Element("Transmission").Attribute("Gears").Value)
                     },
                     // get Engine details for the Car
                     Engine = new Engine()
                     {
                         Type = e.Element("Engine").Attribute("Type").Value,
                         Power = Convert.ToInt32(e.Element("Engine").Attribute("Power").Value)
                     }
                 }).ToList<Car>();

To work over the returned List of cars we can use many methods, one of which is foreach

            foreach (Car car in CarsList)
            {                
                Console.WriteLine(car.Name);                
                Console.WriteLine(car.Engine.Type);
                Console.WriteLine(car.Transmission.ToString());
                Console.WriteLine("--------------");  
            }

here is the output:

Difference Between Debug and Release

Debug:

  • Complete symbolic debug information is emitted to help while debugging applications
  • code optimization is not taken into account
  • Release

  • In release build, symbolic debug information is not emitted.
  • Release build is considerably faster and more optimized
  • Code written in “debug” directive is not included in execution
  • Managing Configuration Details:
    To manage the configuration details for our project we can provide custom configuration by: right click Solution -> configurationManager, or use existing settings by Project –> Propeties / Build.