How to access a web feed (XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

This topic shows how to retrieve and display a web feed using classes in the Windows.Web.Syndication namespace in your Windows Runtime app.

Prerequisites

The following examples use C# or C++ and are based on the Syndication sample. For general help creating a Windows Runtime app using C# or Visual Basic, see Create your first Windows Runtime app using C# or Visual Basic. For general help creating a Windows Runtime app using C++, see Create your first Windows Runtime app using C++.

To ensure your Windows Runtime app is network ready, you must set any network capabilities that are needed in the project Package.appxmanifest file. If your app needs to connect as a client to remote services on the Internet, then the Internet (Client) capability is needed. If the app needs to connect as a client to remote services on a home network or work network, then the Home/Work Networking capability is needed. For more information, see How to set network capabilities.

Retrieving syndicated content from a web feed

The Windows.Web.Syndication.SyndicationClient class retrieves a fully parsed RSS or Atom feed, so instead of tedious explanations about parsing XML, we can move on to more interesting problems. The SyndicationClient class provides only one way to retrieve a feed, and that's asynchronously. The use of the asynchronous programming model is common in the Windows Runtime to help ensure that apps remain responsive. Fortunately, much of the complexity you might expect when using asynchronous methods has been handled for us.

The example code demonstrates how to retrieve a feed, and then display each individual item that the feed contains. Before you can configure and send the request to retrieve a feed, the example code defines a few variables that are used during the operation.

using Windows.Foundation;
using Windows.Web;
using Windows.Web.Syndication;

SyndicationFeed currentFeed = null;
int currentItemIndex = 0;

You first need to check the URI address for the feed to make sure that the string passed contains a valid URI address. A user of your app may have accidentally typed a character that is not allowed in a URI. An exception is thrown when a string that is not valid for a URI is passed to the constructor for the Windows.Foundation.Uri object.

.NET Framework: The System.Uri class is used instead of the Windows.Foundation.Uri class in C# and Visual Basic.

In C# and Visual Basic, this error can be avoided by using the System.Uri class and one of the System.Uri.TryCreate methods to test the string received from the app user before the URI is constructed. In C++, there is no method to try and parse a string to a URI. To catch this exception in that case, use a try/catch block around the C++ code where the URI is constructed.

The code initializes an instance of SyndicationClient which defines the methods and properties you'll use to retrieve and display the feed. Next you configure the request by setting any Server credentials (the ServerCredential property), proxy credentials (the ProxyCredential property), and HTTP headers (the SetRequestHeader method) needed. With the basic request parameters configured, a valid Uri object is then passed to the RetrieveFeedAsync method to request the feed.

You must write code to handle exceptions when you call most asynchronous network methods. Your exception handler can retrieve more detailed information on the cause of the exception to better understand the failure and make appropriate decisions. For more information, see How to handle exceptions in network apps.

The RetrieveFeedAsync method throws an exception if a connection could not be established with the HTTP server or the Uri object does not point to a valid AtomPub or RSS feed. The sample code uses a try/catch block to catch any exceptions and print out more detailed information on the exception if an error occurs.

using Windows.Foundation;
using Windows.Web.Syndication;

private async void GetFeedAsync(string feedUriString)
{
    // The URI is validated by calling Uri.TryCreate() that will 
    // return 'false' for a string that is not a valid URI.
    Uri uri;
    if (!Uri.TryCreate(feedUriString.Text.Trim(), UriKind.Absolute, out uri)) {
        NotifyUser("Error: Invalid URI.";
        return;
    }

    SyndicationClient client = new SyndicationClient();

    // Although most HTTP servers do not require User-Agent header, 
    // others will reject the request or return a different response 
    // if this header is missing. 
    // Use SetRequestHeader() to add custom headers.
    client.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

    try {
        currentFeed = await client.RetrieveFeedAsync(uri);
        NotifyUser("Feed download complete.");

        DisplayFeed();
    }
    catch (Exception ex) {
        SyndicationErrorStatus status = SyndicationError.GetStatus(ex.HResult);
        if (status == SyndicationErrorStatus.InvalidXml) {
            OutputField.Text += "An invalid XML exception was thrown. " +
            "Please make sure to use a URI that points to a RSS or Atom feed.";
        }

        if (status == SyndicationErrorStatus.Unknown) {
            WebErrorStatus webError = WebError.GetStatus(ex.HResult);

            if (webError == WebErrorStatus.Unknown) {
            // Neither a syndication nor a web error. Rethrow.
                throw;
            }
        }

        NotifyUser(ex.Message);
   }
}

The first thing to notice is that the async keyword is added to the GetFeedAsync method signature. You can use the await keyword only in a method that's defined as async. Next, the example code then calls the SyndicationClient.RetrieveFeedAsync method to get the SyndicationClient that contains the RSS or Atom info requested. The await keyword tells the compiler to do a lot of work behind the scenes.

Essentially, the compiler schedules the rest of the method after this call as a callback to be executed when the call returns. It then immediately returns control to the calling thread, typically the UI thread, so that the app remains responsive. When RetrieveFeedAsync returns, the rest of the code in the method is executed.

Once the requested feed content is returned, the example code calls the DisplayFeed method that iterates through available feed items to display the feed. Each of these items is represented using a SyndicationItem object that contains all of the item properties and content afforded by the relevant syndication standard (RSS or Atom).

private void DisplayFeed()
{
    ISyndicationText title = currentFeed.Title;
    FeedTitleField.Text = title != null ? title.Text : "(no title)";

    currentItemIndex = 0; if (currentFeed.Items.Count > 0) {
        DisplayCurrentItem();
    }

    // List the items.
    OutputField.Text += "Items: " + currentFeed.Items.Count + "\r\n";
}

As suggested earlier, the type of content represented by a SyndicationItem object will differ depending on the feed standard (RSS or Atom) employed to publish the feed. For example, an Atom feed is capable of providing a list of contributors, but an RSS feed is not. However, extension elements included in a feed item that are not supported by either standard (e.g., Dublin Core extension elements) can be accessed using the SyndicationItem.elementExtensions property and then displayed.

Summary and next steps

In this topic, we retrieved a feed associated with a supplied URI and displayed the feed content item by item.

For more advanced features like the ability to add, edit, and delete entries within a web feed, see How to manage web feed entries.

Other

Create your first Windows Runtime app using C# or Visual Basic

Create your first Windows Runtime app using C++

How to set network capabilities

How to handle exceptions in network apps

How to manage web feed entries

Reference

SyndicationClient

SyndicationItem

Windows.Web.Syndication

Samples

AtomPub sample

Syndication sample