My pride takes a hit every time I read the title of this post. At least it contains the word “fix”.

People have reported a memory leak on a few occasions, but I’ve never been able to find it and neither have anyone else. I just left it because it has never bothered me. It might be because of a very forgiving hosting partner that just adds more RAM if necessary and never tell me.

Yesterday evening I found myself in the right mood for tracking down this leak and it only took me 6 hours to find it. The fix took about 8 seconds, but what jolly 8 seconds that was.

The problem

After six hours I found that the leak was in the Related Posts server control. The constructor registered an event handler for the Post.Saved event, but the constructor wasn’t static like all the other controls. It was public which means that at every page view the event handler would be registered. That resulted in that the control never got disposed because of the reference to the event. So for each page view, an equal number of controls got stuck in memory and couldn't be garbage collected.

The fix

Make the constructor and event handler static so they only run once in the application life cycle. Let this be a lesson to all, remember to unhook your event handlers. The fix works for BlogEngine.NET 1.3, 1.3.1 and 1.4 and you just have to replace one file in the App_Code folder.

Download the memory leak fix at CodePlex and follow the instructions in the readme.txt.

I’m sorry it took so long to find this fix. I hope it hasn’t caused you too much trouble.

BlogEngine.NEXT

In the light of this and other bugs, we have decided to do a service release in a couple of weeks. Beside the memory leak fix, it will include many other tweaks, fixes and a few new minor features. It will be 100% backwards compatible with the current 1.4 release. If you have found some issues with 1.4 that you want fixed in the next release, please add them to the issue tracker.

Today, I’ve been updating the BlogEngine.NET Gravatar support to include the new fallback types that Gravatar introduced a few months ago.

A Gravatar is an image that is associated with an e-mail address if the owner of the e-mail address has registered with Gravatar.

If an e-mail address doesn’t have an associated image, Gravatar serves a fallback image instead. Before, the fallback image could either be the default blue Gravatar logo or a URL to an image on the web. Now they have introduced three new fallback image types:


MonsterID


Identicons


Wavatars

This is really cool because now we don’t need to implement our own fallback images in BlogEngine.NET or any other web application for that matter. BlogEngine.NET has had its own implementation of the MonsterID and Subtext uses Identicons. Now none of these projects have to maintain that code anymore. I just deleted all the MonsterID images and that freed several megabytes of disk space.

Example

Here is an example on how to use the new Gravatar fallback types in ASP.NET. First we have to create a method that generates the correct Gravatar URL:

/// <summary>

/// Creates a URL to the Gravatar associated with the email address.

/// </summary>

/// <remarks>

/// The fallback parameter can either be a fully qualified URL to a custom

/// image located on the web or it can be "monsterid", "wavatar" or "identicon".

/// In case a null or an empty string is passed as a fallback, the default blue

/// Gravatar image will be shown.

/// </remarks>

/// <param name="email">The email is the key to find the right Gravatar.</param>

/// <param name="size">The size of the returned Gravatar in pixels.</param>

/// <param name="fallback">The fallback if no Gravatar exists.</param>

/// <returns></returns>

public static string Gravatar(string email, int size, string fallback)

{

  if (string.IsNullOrEmpty(email))

    throw new ArgumentNullException("email", "Email must be specified");

 

  if (!string.IsNullOrEmpty(fallback) && fallback.StartsWith("http"))

    fallback = HttpUtility.UrlEncode(fallback);

 

  email = email.ToLowerInvariant().Trim();

  string hash = FormsAuthentication.HashPasswordForStoringInConfigFile(email, "MD5").ToLowerInvariant();

  return "http://www.gravatar.com/avatar/" + hash + ".jpg?s=" + size + "&d=" + fallback;

}

And then call it from an image tag on the web page.

<img src="<%=Gravatar("mail@example.com", 60, "wavatar") %>" alt="Gravatar" />

It's as simple as that.