Demystifying The Code

Exposing ATOM feeds from your services

One of the key enabling factors of the browsable web was the use of a standard representation format: HTML.  Web page authors need only understand one format and browsers need only understand how to render one format.  In other words, if I authored a web page in HTML, it was easily consumable because every browser understood our standard representation format.  This same concept can and does hold true for our RESTful services.  If my service returns a standard representation format like ATOM, there are already a host of clients that can consume the response.  Conversely, if my service returns POX (plain old XML), we are starting at ground zero.

The key to choosing a representation format is to choose one that is standardized, fits your problem domain and is widely understood in that domain.  The ATOM Syndication Format is a standardized XML-Based format for web feeds.  While, arguably, the original purpose for the format was for (we)blogs, it is now used for a variety of purposes and is widely understood.  A key to the success of the ATOM Syndication Format is that it is extensible.  This post will illustrate how to easily expose an ATOM Feed from your RESTful service by taking advantage of the WCF REST Starter Kit.  A second post will further illustrate how to extend the format to expose some custom data.  If you have been following some of my other posts or screencasts on REST, you might guess that I will be exposing a feed of wines from my wine catalog.

 

Watch the Screencast

You can watch the screencast on Channel9.

 

The WCF REST Starter Kit

The WCF REST Starter Kit is a toolkit that provides Visual Studio templates, samples and a dll (Microsoft.ServiceModel.Web.dll) that provides some great functionality.  While, in my opinion, the most compelling features of the starter kit are in Microsoft.ServiceModel.Web and the samples, the templates provide some great guidance, as well.  (Some of my other blog posts illustrate the poser of the dll and samples.)  This post will be taking advantage of the item templates.  Click here to download the starter kit.

 

Creating a generic ATOM Feed

For the purposes of this sample, I am starting with a web site and some code that returns a collection of my wines.  More about that later.  Here is a snapshot of my solution explorer:

image

The process of creating a sample ATOM Feed is brain-dead simple thanks to the starter kit.  All you need to do is:

  1. Right-Click your web and choose Add New Item
  2. Choose the WCF ATOM Feed Service template (it is under My Templates with the Language set to C#")
    image

As you can see from above, I named my service WineService.svc.  So, what did the template create?  It created a RESTful WCF service that returns an ATOM feed.  More specifically, it created 2 files: WineService.svc and WineService.cs (if you are using a web site, this will be in the App_Code directory).  We will spend most of our time on the cs file, but let’s take a brief look at the svc file.

 

WineService.svc

image

As you can see above, the service uses the configurationless model.  In other words, it defines a Factory that sets up the appropriate service host.  This is in lieu of adding all of the configuration settings in the web.config.  As you can see from my comments above, that the template set up a custom ServiceHostFactory that returns a WebServiceHost2.  This is a very cool new service host that is courtesy of the WCF REST Starter Kit.  As cool as this new service host is (you will have to read my other blog posts to see why), it does not provide any ATOM functionality here.  You can replace this with the following and it will work just fine:

image

The net-net here is that the svc file declares a factory that sets up the appropriate ServiceHost, specifically some form of WebServiceHost which sets up a RESTful endpoint.  No web.config settings are required.  If you are a true geek and you care, this means that the binding is set to webHttpBinding and the endpoint has an endpointBehavior of webHttp.

 

WineService.cs

This is where the real ATOM work is being done.  There is a lot of code and comments in this class file.  I am going to concentrate on what is salient to creating an ATOM feed, so I will not discuss each and every line.  Let’s start with the class and method declarations:

image

The template output a class named FeedService and decorated it with the ServiceModel attribute, telling WCF to expose any methods in the class that are decorated with OperationContract as service operations.  The class contains one method named GetFeed.  That method is decorated with the OperationContract attribute, so it will be exposed as a service method.  The method is further decorated with a WebGet attribute to indicate that this service will be exposed with an HTTP GET (instead of the default of HTTP POST).  You will also notice that a UriTemplate is set to “?numItems={i}”.  The UriTemplate allows you to control the portion of the URI after the path to the service (normally the path to the svc file).  (click here for more on UriTemplates)  In this case, the UriTemplate allows us to pass a parameter, i, that will automatically be mapped to the i argument on GetFeed.  This argument determines how many sample feed items to create.  The last thing to point out here is that the return type of the method is an Atom10FeedFormatter.  This type serializes SyndicationFeed-derived classes to and from the Atom 1.0 format.

The next bit of code starts with declaring a SyndicationFeed.  It then ensures a value > 0 was passed for the number of sample items to create.  Lastly, it news up a collection of SyndicationItems.

image

Next, we run through a loop to create the passed in amount of syndication items.  Notice that this code is using an object initializer to create an instance of a SyndicationItem and set the Id, Title, LastUpdatedTime, Authors and Content properties.  It also adds the newly created SyndicationItem into the collection of SyndicationItems declared earlier.  I have underlined in red where the template provides some guidance on what you should include in your feed items according to the ATOM specs.  Obviously, all of the values are bogus data.  This is where you would enter your real information.  Lastly, notice that we set the Content property to text content.  When we personalize this example, we will set this to xml.  Essentially, we will extend the spec.

image

Next, we create the instance of our SyndicationFeed.  We again use an object initializer to set the Id, Title and Items property on the feed.  Notice that here, we are setting the Items to the collection of SyndicationItems we just created.  Before we return our feed, we get a reference to the outgoing response and set the content type to ATOM.  This results in the Content-Type HTTP header being set to application/atom + xml.  It is important to note that the SyndicationFeed we have created can be used to output an ATOM feed or an RSS feed.  We need to call GetAtom10Formatter to get our Atom10FeedFormatter.

image

 

Running the Sample

That is it.  We can run this sample and see how IE handles ATOM data:

image

As you can see, IE knows how to parse ATOM Feeds.  If you are seeing xml and not this view, you need to turn on feed reading.  You can do that by clicking on Tools | Internet Options.  Under the content tab, click Settings.

image

Then check the ‘Turn on feed reading view’ checkbox.

image

When developing, I keep this unchecked as I like to see the raw xml.  Most of my feeds extend ATOM, so I want to see all of the XML.  In tomorrow’s post, I’ll illustrate how to take this sample that was created from the Visual Studio Item Template and update it to expose custom data.  Feel free to watch the screencast on Channel9.

Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!

Demystifying The Code