Export (0) Print
Expand All

How to: Expose a Feed as both Atom and RSS

Windows Communication Foundation (WCF) allows you to create a service that exposes a syndication feed. This topic discusses how to create a syndication service that exposes a syndication feed using both Atom 1.0 and RSS 2.0. This service exposes one endpoint that can return either syndication format. For simplicity the service used in this sample is self hosted. In a production environment a service of this type would be hosted under IIS or WAS. For more information about the different WCF hosting options, see Hosting of Windows Communication Foundation Services.

To create a basic syndication service

  1. Define a service contract using an interface marked with the WebGetAttribute attribute. Each operation that is exposed as a syndication feed returns a SyndicationFeedFormatter object. Note the parameters for the WebGetAttribute. UriTemplate specifies the URL used to invoke this service operation. The string for this parameter contains literals and a variable in braces ({format}). This variable corresponds to the service operation's format parameter. For more information, see UriTemplate. BodyStyle affects how the messages that this service operation sends and receives are written. Bare specifies that the data sent to and from this service operation are not wrapped by infrastructure-defined XML elements. For more information, see WebMessageBodyStyle.

    [ServiceContract]
    [ServiceKnownType(typeof(Atom10FeedFormatter))]
    [ServiceKnownType(typeof(Rss20FeedFormatter))]
    public interface IBlog
    {
        [OperationContract]
        [WebGet(UriTemplate = "GetBlog?format={format}")]
        SyndicationFeedFormatter GetBlog(string format);
    }
    
    
    Bb412205.note(en-us,VS.90).gifNote:
    Use the ServiceKnownTypeAttribute to specify the types that are returned by the service operations in this interface.

  2. Implement the service contract.

    public class BlogService : IBlog
    {
        public SyndicationFeedFormatter GetBlog(string format)
        {
            SyndicationFeed feed = new SyndicationFeed("My Blog Feed", "This is a test feed", new Uri("http://SomeURI"));
            feed.Authors.Add(new SyndicationPerson("someone@microsoft.com"));
            feed.Categories.Add(new SyndicationCategory("How To Sample Code"));
            feed.Description = new TextSyndicationContent("This is a sample that demonstrates how to expose a feed through RSS and Atom with WCF");
            SyndicationItem item1 = new SyndicationItem(
                "Item One",
                "This is the content for item one",
                new Uri("http://localhost/Content/One"),
                "ItemOneID",
                DateTime.Now);
    
            SyndicationItem item2 = new SyndicationItem(
                "Item Two",
                "This is the content for item two",
                new Uri("http://localhost/Content/Two"),
                "ItemTwoID",
                DateTime.Now);
    
            SyndicationItem item3 = new SyndicationItem(
                "Item Three",
                "This is the content for item three",
                new Uri("http://localhost/Content/three"),
                "ItemThreeID",
                DateTime.Now);
            List<SyndicationItem> items = new List<SyndicationItem>();
            items.Add(item1);
            items.Add(item2);
            items.Add(item3);
    
            feed.Items = items;
    
            if (format == "rss")
                return new Rss20FeedFormatter(feed);
            else if (format == "atom")
                return new Atom10FeedFormatter(feed);
            else return null;
        }
    }
    
    
  3. Create a SyndicationFeed object and add an author, category, and description.

    SyndicationFeed feed = new SyndicationFeed("My Blog Feed", "This is a test feed", new Uri("http://SomeURI"));
    feed.Authors.Add(new SyndicationPerson("someone@microsoft.com"));
    feed.Categories.Add(new SyndicationCategory("How To Sample Code"));
    feed.Description = new TextSyndicationContent("This is a sample that demonstrates how to expose a feed through RSS and Atom with WCF");
    
    
  4. Create several SyndicationItem objects.

    SyndicationItem item1 = new SyndicationItem(
        "Item One",
        "This is the content for item one",
        new Uri("http://localhost/Content/One"),
        "ItemOneID",
        DateTime.Now);
    
    SyndicationItem item2 = new SyndicationItem(
        "Item Two",
        "This is the content for item two",
        new Uri("http://localhost/Content/Two"),
        "ItemTwoID",
        DateTime.Now);
    
    SyndicationItem item3 = new SyndicationItem(
        "Item Three",
        "This is the content for item three",
        new Uri("http://localhost/Content/three"),
        "ItemThreeID",
        DateTime.Now);
    
    
  5. Add the SyndicationItem objects to the feed.

    List<SyndicationItem> items = new List<SyndicationItem>();
    items.Add(item1);
    items.Add(item2);
    items.Add(item3);
    
    feed.Items = items;
    
    
  6. Use the format parameter to return the requested format.

    if (format == "rss")
        return new Rss20FeedFormatter(feed);
    else if (format == "atom")
        return new Atom10FeedFormatter(feed);
    else return null;
    
    

To host the service

  1. Create a WebServiceHost object. The WebServiceHost class will automatically add an endpoint at the service's base address unless one is specified in code or configuration. In this sample, no endpoints are specified so the default endpoint will be exposed.

    Uri address = new Uri("http://localhost:8000/BlogService/");
    WebServiceHost svcHost = new WebServiceHost(typeof(BlogService), address);
    
    
  2. Open the service host, load the feed from the service, display the feed, and wait for the user to press ENTER.

    svcHost.Open();
    Console.WriteLine("Service is running");
    
    Console.WriteLine("Loading feed in Atom 1.0 format.");
    XmlReader atomReader = XmlReader.Create("http://localhost:8000/BlogService/GetBlog?format=atom");
    SyndicationFeed atomFeed = SyndicationFeed.Load(atomReader);
    Console.WriteLine(atomFeed.Title.Text);
    Console.WriteLine("Items:");
    foreach (SyndicationItem item in atomFeed.Items)
    {
        Console.WriteLine("Title: {0}", item.Title.Text);
        Console.WriteLine("Content: {0}", ((TextSyndicationContent)item.Content).Text);
    }
    
    Console.WriteLine("Loading feed in RSS 2.0 format.");
    XmlReader rssReader = XmlReader.Create("http://localhost:8000/BlogService/GetBlog?format=rss");
    SyndicationFeed rssFeed = SyndicationFeed.Load(rssReader);
    Console.WriteLine(rssFeed.Title.Text);
    Console.WriteLine("Items:");
    foreach (SyndicationItem item in rssFeed.Items)
    {
        Console.WriteLine("Title: {0}", item.Title.Text);
        // Notice we are using item.Summary here instead of item.Content. This is because
        // of the differences between Atom 1.0 and RSS 2.0 specs.
        Console.WriteLine("Content: {0}", ((TextSyndicationContent)item.Summary).Text);
    }
    
    Console.WriteLine("Press <ENTER> to quit...");
    Console.ReadLine();
    svcHost.Close();
    
    

To call GetBlog with an HTTP GET

  1. Open Internet Explorer, type the following URL, and press ENTER. http://localhost:8000/BlogService/GetBlog

    The URL contains the base address of the service (http://localhost:8000/BlogService), the relative address of the endpoint, and the service operation to call.

To call GetBlog() from code

  1. Create an XmlReader with the base address and the method you are calling.

    XmlReader reader = XmlReader.Create("http://localhost:8000/BlogService/GetBlog?format=atom");
    
    
  2. Call the static Load method, passing in the XmlReader you just created.

    SyndicationFeed feed = SyndicationFeed.Load(reader);
    
    

    This invokes the service operation and populates a new SyndicationFeed with the formatter returned from the service operation.

  3. Access the feed object.

    Console.WriteLine(feed.Title.Text);
    Console.WriteLine("Items:");
    foreach (SyndicationItem item in feed.Items)
    {
        Console.WriteLine("Title: {0}", item.Title.Text);
        Console.WriteLine("Content: {0}", ((TextSyndicationContent)item.Content).Text);
    }
    
    

Example

The following is the full code listing for this example.

using System;
using System.Xml;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
namespace Service
{
    [ServiceContract]
    [ServiceKnownType(typeof(Atom10FeedFormatter))]
    [ServiceKnownType(typeof(Rss20FeedFormatter))]
    public interface IBlog
    {
        [OperationContract]
        [WebGet(UriTemplate = "GetBlog?format={format}")]
        SyndicationFeedFormatter GetBlog(string format);
    }

    public class BlogService : IBlog
    {
        public SyndicationFeedFormatter GetBlog(string format)
        {
            SyndicationFeed feed = new SyndicationFeed("My Blog Feed", "This is a test feed", new Uri("http://SomeURI"));
            feed.Authors.Add(new SyndicationPerson("someone@microsoft.com"));
            feed.Categories.Add(new SyndicationCategory("How To Sample Code"));
            feed.Description = new TextSyndicationContent("This is a sample that demonstrates how to expose a feed through RSS and Atom with WCF");
            SyndicationItem item1 = new SyndicationItem(
                "Item One",
                "This is the content for item one",
                new Uri("http://localhost/Content/One"),
                "ItemOneID",
                DateTime.Now);

            SyndicationItem item2 = new SyndicationItem(
                "Item Two",
                "This is the content for item two",
                new Uri("http://localhost/Content/Two"),
                "ItemTwoID",
                DateTime.Now);

            SyndicationItem item3 = new SyndicationItem(
                "Item Three",
                "This is the content for item three",
                new Uri("http://localhost/Content/three"),
                "ItemThreeID",
                DateTime.Now);
            List<SyndicationItem> items = new List<SyndicationItem>();
            items.Add(item1);
            items.Add(item2);
            items.Add(item3);

            feed.Items = items;

            if (format == "rss")
                return new Rss20FeedFormatter(feed);
            else if (format == "atom")
                return new Atom10FeedFormatter(feed);
            else return null;
        }
    }

    public class Host
    {
        static void Main(string[] args)
        {
            Uri address = new Uri("http://localhost:8000/BlogService/");
            WebServiceHost svcHost = new WebServiceHost(typeof(BlogService), address);
            try
            {
                svcHost.Open();
                Console.WriteLine("Service is running");

                Console.WriteLine("Loading feed in Atom 1.0 format.");
                XmlReader atomReader = XmlReader.Create("http://localhost:8000/BlogService/GetBlog?format=atom");
                SyndicationFeed atomFeed = SyndicationFeed.Load(atomReader);
                Console.WriteLine(atomFeed.Title.Text);
                Console.WriteLine("Items:");
                foreach (SyndicationItem item in atomFeed.Items)
                {
                    Console.WriteLine("Title: {0}", item.Title.Text);
                    Console.WriteLine("Content: {0}", ((TextSyndicationContent)item.Content).Text);
                }

                Console.WriteLine("Loading feed in RSS 2.0 format.");
                XmlReader rssReader = XmlReader.Create("http://localhost:8000/BlogService/GetBlog?format=rss");
                SyndicationFeed rssFeed = SyndicationFeed.Load(rssReader);
                Console.WriteLine(rssFeed.Title.Text);
                Console.WriteLine("Items:");
                foreach (SyndicationItem item in rssFeed.Items)
                {
                    Console.WriteLine("Title: {0}", item.Title.Text);
                    // Notice we are using item.Summary here instead of item.Content. This is because
                    // of the differences between Atom 1.0 and RSS 2.0 specs.
                    Console.WriteLine("Content: {0}", ((TextSyndicationContent)item.Summary).Text);
                }

                Console.WriteLine("Press <ENTER> to quit...");
                Console.ReadLine();
                svcHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                svcHost.Abort();
            }
        }
    }
}

Compiling the Code

When compiling the previous code, reference System.ServiceModel.dll and System.ServiceModel.Web.dll.

See Also


© 2007 Microsoft Corporation. All rights reserved.
Last Published: 2010-03-21
Show:
© 2014 Microsoft