The hCard microformat is used to make contact information machine readable. In BlogEngine.NET 1.4.5 this is being supported in the post comments. However, if you are writing your own custom theme, you need to add a little bit of code to your CommentView.ascx theme file.

The themes bundled in BlogEngine.NET 1.4.5 already have these small pieces of code embedded, so let’s take a look at the Standard theme’s CommentView.ascx file.

The containing <div> now have two classes: vcard and comment. The vcard class is new and is the one that triggers the hCard microformat. It looks like this:

<div id="id_<%=Comment.Id %>" class="vcard comment...

If the vcard class is added, machines will expect to find an hCard microformat within that <div>, but we need to add one more class to make it a valid hCard – the fn class name.

In the Standard theme’s CommentView.ascx file you can see where the name of the comment author is written. If it author supplied her website URL an hyperlink is created, otherwise a span tag. The hyperlink has a class attribute with two class names: fn and url. This tells the hCard crawlers that this is both the full name and the URL of the contact. In the span, only the fn class name is needed.

So, if you want to support microformats in your custom themes; take a look at the Standard theme’s CommentView.ascx file and make the appropriate modifications. BlogEngine.NET 1.4.5 already adds the appropriate classes to the avatar image and country flag, so you don’t have to do anything there.

For some strange reason I couldn’t figure out why some websites would return status 500 internal server error when they were retrieved using a WebClient in C#. The same page would render fine using a browser. It was only once in a while it happened.

I thought it might have something to do with the WebClient class so I tried using an HttpWebRequest and HttpWebResponse instead, but the result was the same. Then I started Fiddler to construct requests and tried out different HTTP headers. This let me to the problem and the solution.

The problem was that some websites use certain headers without checking if they exist or not. In this case it was the Accept-Encoding and Accept-Language headers that were missing from my request. The solution is the method below.

/// <summary>

/// Downloads a web page from the Internet and returns the HTML as a string. .

/// </summary>

/// <param name="url">The URL to download from.</param>

/// <returns>The HTML or null if the URL isn't valid.</returns>

public static string DownloadWebPage(Uri url)

{

  try

  {

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

    request.Headers["Accept-Encoding"] = "gzip";

    request.Headers["Accept-Language"] = "en-us";

    request.Credentials = CredentialCache.DefaultNetworkCredentials;

    request.AutomaticDecompression = DecompressionMethods.GZip;

 

    using (WebResponse response = request.GetResponse())

    {

      using (StreamReader reader = new StreamReader(response.GetResponseStream()))

      {

        return reader.ReadToEnd();

      }

    }

  }

  catch (Exception)

  {

    return null;

  }

}

This is one of those things that seem obvious when you know the way around it. It still didn't stop me from using an hour tracking it down. Doh!