This was too easy/cool to keep tucked away. I wanted the most cheap and cheerful way of listing the top 10 blog posts, into a larger, containing website I am building for a client. I started out by Googling (googeloper) “wordpress integration c#”. Unexpectedly, nothing obvious I was looking for surfaced. Most solution seemed to rely on having WordPress installed physically beneath the website, or proposed options such as FTP based integration. Yuck! No. I just wanted the 10 latest posts in real time (i.e. as of now). Hold on I thought, that’s exactly what feeds have been designed to do. Blog engines (such as WordPress) have excellent feed support, including a REST based API, support for RSS and Atom. Wowzers.
There is plenty of good information about those topics elsewhere. I really just wanted to demonstrate how simple it is to query such a feed taking a server side approach (assuming your web server has Internet HTTP GET access to the feed). To do this, I used System.Net.WebClient, LINQ to XML and ASP.NET MVC 3. The feed I am consuming is for a WordPress blog, but there is absolutely no dependency/coupling that the blog must be WordPress based. It could for example, be a Blogger feed.
Another factor that should be given consideration is whether taking a server side (e.g. ASP.NET) approach versus a client side (e.g. jQuery) approach is a better fit for you. If for example search engine visibility (SEO) of the integrated blog content is important to you, a server side approach may be a better fit.
1. Using a browser review the feed you’re targeting. For example, if the (WordPress) blog is http://example.com then have a look at http://example.com/feed/ or http://example.com/feed/atom. Below is a sample of the first chunk of Atom feed for this WordPress blog.
<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en" xml:base="http://bencode.net/wp-atom.php" xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" > <title type="text">benCode</title> <subtitle type="text">Ben Simmonds: BizTalk Server Guy in Sydney</subtitle> <updated>2010-11-24T02:03:03Z</updated> <link rel="alternate" type="text/html" href="http://bencode.net" /> <id>http://bencode.net/feed/atom/</id> <link rel="self" type="application/atom+xml" href="http://bencode.net/feed/atom/" /> <generator uri="http://wordpress.com/">WordPress.com</generator> <link rel="search" type="application/opensearchdescription+xml" href="http://bencode.net/osd.xml" title="benCode" /> <link rel="search" type="application/opensearchdescription+xml" href="http://wordpress.com/opensearch.xml" title="WordPress.com" /> <link rel='hub' href='http://bencode.net/?pushpress=hub' /> <entry> <author> <name>beness</name> <uri>http://www.bencode.net/</uri> </author> <title type="html"><![CDATA[SSO Configuration Road Block]]></title> <link rel="alternate" type="text/html" href="http://bencode.net/2010/11/24/sso-configuration-road-block/" /> <id>https://bencode.wordpress.com/2010/11/24/sso-configuration-road-block/</id> <updated>2010-11-24T02:03:03Z</updated> <published>2010-11-24T01:58:25Z</published> <category scheme="http://bencode.net" term="BizTalk" /><category scheme="http://bencode.net" term="SSO" /><category scheme="http://bencode.net" term="Error" /> <summary type="html"><![CDATA[Recently I’ve had the need to setup a BizTalk Server 2006 R2 virtual machine. Quietly confident about my experience with this version of BizTalk, I jumped in head first to *quickly* get a simple single server based installation configured on a 32-bit VMWare based VM. Lesson learned today…never, ever underestimate the obscure errors that BizTalk [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bencode.net&blog=2452880&post=109&subd=bencode&ref=&feed=1" width="1" height="1" />]]></summary> <content type="html" xml:base="http://bencode.net/2010/11/24/sso-configuration-road-block/"><![CDATA[<p>Recently I’ve had the need to setup a BizTalk Server 2006 R2 virtual machine. Quietly confident about my experience with this version of BizTalk, I jumped in head first to *quickly* get a simple single server based installation configured on a 32-bit VMWare based VM.</p>
2. Below is a snippet of simple C# that leverages LINQ to XML to parse an Atom feed. This code is in a controllers action method, because of ASP.NET MVC, but again this code has no requirement for you to be using MVC. Side note: LINQ to XML makes working with XML much more fluid for the C#/VB developer. Very very nice to use!
public ActionResult Index()
{
XNamespace xsd = "http://www.w3.org/2005/Atom";
var client = new WebClient();
var feed = client.DownloadString("http://www.bencode.net/feed/atom");
var document = XDocument.Parse(feed);
var blogs =
from e in document.Descendants(xsd + "entry")
select new BlogModel()
{
Title = (string)e.Element(xsd + "title"),
Content = new HtmlString((string)e.Element(xsd + "content"))
};
return View(blogs);
}
3. A simple MVC 3 Razor view:
@model IEnumerable<MvcApplication.Model.BlogModel>
@{
View.Title = "Blogs";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Blogs</h1>
@foreach (var blog in Model) {
<div class="blogpost">
<h2>@blog.Title</h2>
<p>@blog.Content</p>
</div>
}
4. Downloading, streaming, parsing and rendering this feed should be considered an expensive operation. Something that you probably don’t want to happen for each request that comes in for your page/site. To cache this entire “pipeline” of work, I went with some ASP.NET MVC output caching, by marking up the controller action with the following custom attribute:
[OutputCache(VaryByParam="none", Duration=60)]
public ActionResult Index()
{
...
The result:



