Consuming a blog RSS using LINQ to XML

Hello,

While setting up our corporate Blogs I was tasked with displaying our blog RSS feeds on the corporate domain.  I’ve previously accomplished this in asp.net by parsing the feed and displaying the results however this time I wanted to try something a little different.

Recently I’ve started to use LINQ a lot in my development efforts to rapidly query data that otherwise would require more plumbing.  While surfing across the blogosphere I came across the following post from Scott Guthrie.  This was pretty much what I was looking for with the exception of adding some data caching.

The following is my method for retrieving the posts for a feed and converting it into a strongly typed list which we then can cache as desired:

public List<BlogPost> LoadPosts(string blogGuid, List<FeedDefinition> feedList)
{
    // Variables
    List<BlogPost> blogPosts = new List<BlogPost>();
    FeedDefinition currentFeed = new FeedDefinition();

    // Look for the matching feed
    foreach (FeedDefinition feed in feedList)
    {
        if (feed.Guid == blogGuid)
        {
            // Found a match
            currentFeed = feed;
            break;
        }
    }

    #region Load Blog Entries
    double cacheDuration = Convert.ToDouble(ConfigurationManager.AppSettings["cacheDuration"]);

    // Define XML Namespaces
    XNamespace slashNamespace = "http://purl.org/rss/1.0/modules/slash/";
    XNamespace dcNamespace = "http://purl.org/dc/elements/1.1/";

    // Load the rss feed
    XDocument rssFeed = XDocument.Load(currentFeed.Url);

    // Check if Cached
    if (Cache[currentFeed.Guid] == null)
    {
        // Query for Posts
        var posts = from item in rssFeed.Descendants("item")
                    select new BlogPost
                    {
                        Title = item.Element("title").Value,
                        Author = item.Element(dcNamespace + "creator").Value,
                        Description = item.Element("description").Value,
                        Published = DateTime.Parse(item.Element("pubDate").Value),
                        Url = item.Element("link").Value,
                        Tags = (from category in item.Elements("category")
                                orderby category.Value
                                select category.Value).ToList()
                    };
        blogPosts = posts.ToList();

        // Add to cache
        Cache.Add(currentFeed.Guid, blogPosts, null, DateTime.Now.AddMinutes(cacheDuration), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
    }
    else
    {
        blogPosts = (List<BlogPost>)Cache[currentFeed.Guid];
    }
    #endregion

    return blogPosts;
}

Here’s what the BlogPost class looks like:

public class BlogPost
{
    public String Title { get; set; }
    public String Author { get; set; }
    public String Description { get; set; }
    public DateTime Published { get; set; }
    public String Url { get; set; }
    public List<string> Tags { get; set; }
}

The blogGuid is the currently selected blog link from the navigation.  Since this was snipped as part of an in-use project I can’t post the full solution as-is however hopefully there is enough detail there to see where using LINQ to select into a strongly typed class can really shorten the code required to extract the data we are looking for.

In a later post I hope to investigate using the CRM 4.0 Notifications Accelerator to generate a News RSS feed that can be consumed and displayed on a website.

Leave a Reply

Your email address will not be published. Required fields are marked *