Consuming WordPress RSS Feed In ASP.NET

Solution:1

You can use LINQ to XML to read a WordPress RSS feed.

First get the feed. Make a Uri instance out of it.

var rssFeed = new Uri("https://github.com/geersch/feed/");

Then perform a GET request.

var request = (HttpWebRequest) WebRequest.Create(rssFeed);
request.Method = "GET";
var response = (HttpWebResponse) request.GetResponse();

Get the response stream and read it to download the contents of the feed.

using (var reader = new StreamReader(response.GetResponseStream()))
{
    var feedContents = reader.ReadToEnd();
    //...
}

Still within the above using statement use LINQ to XML to parse the downloaded content and extract the information you need.

var document = XDocument.Parse(feedContents);

var posts = (from p in document.Descendants("item")
             select new
             {
                 Title = p.Element("title").Value,
                 Link = p.Element("link").Value,
                 Comments = p.Element("comments").Value,
                 PubDate = DateTime.Parse(p.Element("pubDate").Value)
             }).ToList();

Now you can iterate over the results.

foreach(var post in posts)
{
    Console.WriteLine(post.Title);
    Console.WriteLine(post.Link);
    Console.WriteLine(post.Comments);
    Console.WriteLine(post.PubDate);
}

Here I just used an anonymous type to capture the output in, but feel free to create your own BlogPost class or something similar which you can use in the LINQ query.

I’m used to C#, so that’s why I’ve used it in my reply. But you can easily convert it. There are some online converters which you can use.

Regarding your issue with the DataSet (which I personally would not use to implement this), it is caused by an item (blog post) having nodes with the same name.

For example:

<comments>...</comments>
<slash:comments>5</slash:comments>

Sure the second one has a different namespace (slash), but DataSet’s ReadXml(…) method does not care about namespaces. It tries to create a second column named “comments”. That is why you get the exception.

You can still use a DataSet / DataTable if you want to. Just extract the data from the feed using LINQ to XML as shown above.

Then create a DataSet and add a new table to it.

var dataSet = new DataSet();
var blog = new DataTable("Blog");
blog.Columns.Add("Title", typeof(string));
blog.Columns.Add("Link", typeof(string));
blog.Columns.Add("Comments", typeof(string));
dataSet.Tables.Add(blog);

Iterate over the extracted data and add it to the DataTable:

foreach (var post in posts)
{
    var newRow = blog.NewRow();
    newRow["Title"] = post.Title;
    newRow["Link"] = post.Link;
    newRow["Comments"] = post.Comments;

    blog.Rows.Add(newRow);
 }

Voila, we’ve now fixed your issue by no longer relying on the DataSet’s ReadXml(…) method. Download the feed, extract the data you are interested in and persist it.

Solution:2

Structure of an RSS Feed

RSS feeds have the following basic structure. Other information is contained within them but for the purposes of brevity, these have been removed.

XML
<rss>
  <channel>
    <item>
      <title></title>
      <link></link>
      <description></description>
      <pubDate></pubDate>
    </item>
  </channel>
</rss>

The information that I was interested in for my web site were the TitleLinkDescription and Publication Date items from the RSS feed.

Consuming an RSS Feed

There are several different ways to achieve this, so this is just one way. I have implemented this using an ASP.NET web form but the general principle can be applied to other technologies.

  1. Firstly, I added a Gridview control to my web page. A Repeater control is also perfectly acceptable.
    ASP.NET
    <asp:GridView ID="gvRss" runat="server">
      <Columns>
        <asp:TemplateField>
          <ItemTemplate>
            <table width="100%" border="0" cellpadding="0" cellspacing="5">
              <tr>
                <h3 style="color:#3E7CFF"><%#Eval("Title") %></h3>
              </tr>
              <tr>
                <%#Eval("PublishDate") %>
              </tr>
              <tr>
                <td colspan="2">
                  <hr />
                  <%#Eval("Description") %>
                </td>
              </tr>
              <tr>
                <td> </td>
                <td align="right">
                  <a href='<%#Eval("Link") %>' target="_blank">Read More...</a>
                </td>
              </tr>
            </table>
          </ItemTemplate>
        </asp:TemplateField>
      </Columns>
    </asp:GridView>
  2. In the code behind, I have added a new method to populate the Gridview control with data from the RSS feed as follows:
    C#
    protected void Page_Load(object sender, EventArgs e)
    {
        this.PopulateRssFeed();
    }
    
    private void PopulateRssFeed()
    {
        string rssFeedUrl = ConfigurationManager.AppSettings["RssFeedUrl"];
        List<feeds> feeds = new List<feeds>();
        XDocument xDoc = XDocument.Load(rssFeedUrl);
        var items = (from x in xDoc.Descendants("item")
                     select new
                         {
                             title = x.Element("title").Value,
                             link = x.Element("link").Value,
                             pubDate = x.Element("pubDate").Value,
                             description = x.Element("description").Value
                         });
        if (items != null)
        {
            feeds.AddRange(items.Select(i => new Feeds
                {
                    Title = i.title, Link = i.link, PublishDate = i.pubDate, Description = i.description
                }));
        }
        gvRss.DataSource = feeds;
        gvRss.DataBind();
    }
  3. I then created a simple POCO Feed class that mapped the RSS feed items to the Gridview control.
    C#
    public class Feeds
    {
        public string Title { get; set; }
        public string Link { get; set; }
        public string PublishDate { get; set; }
        public string Description { get; set; }
    }
  4. I store the URL to my RSS feed in the web.config. This ensures that the URL can be easily changed if necessary.
    XML
    <appSettings>
      <add key="RssFeedUrl" value="http://www.somedomain.com/rssfeed.rss"/>
    </appSettings>