UPDATE: BlogEngine 1.6.0.1 will fix this problem

Download BlogEngine 1.6 Binary Patch (drop in your bin folder)

We recently installed an open source error logging project called Elmah on our BlogEngine.NET because we noticed that comments were broken on our blog and some people informed us of other errors.

After installing Elmah, we found out that we had a lot of exceptions like this:

The file '/post/2008/01/Attach-to-Process-with-one-shortcut.aspx' does not exist.

After some investigation, we found out that a lot of the links leading to our blog were broken!  This is bad news because we care about our Google rankings!

I investigated the BlogEngine.NET code a little bit because we considered this a major problem and found out that BlogEngine.NET changed the link pattern from:

http://blog.lavablast.com/post/2008/02/I2c-for-one2c-welcome-our-new-revision-control-overlords!.aspx  (the old pattern)

to

http://blog.lavablast.com/post/2008/02/11/I2c-for-one2c-welcome-our-new-revision-control-overlords!.aspx  (the new pattern)

The day is now required in the link. Otherwise, external links are redirected to an error page.

After investigating the code, I found out that the method RewritePost in the class BlogEngine.Core.Web.HttpModules.UrlRewrite was changed in svn revision 29143 from:

Post post = Post.Posts.Find(delegate(Post p)
{
    if (date != DateTime.MinValue && (p.DateCreated.Year != date.Year || p.DateCreated.Month != date.Month))
    {
        if (p.DateCreated.Day != 1 && p.DateCreated.Day != date.Day)
            return false;
    }
 
    return slug.Equals(Utils.RemoveIllegalCharacters(p.Slug), StringComparison.OrdinalIgnoreCase);
});
 

to

Post post = Post.Posts.Find(delegate(Post p)
{
    if (date != DateTime.MinValue &&
        (p.DateCreated.Year != date.Year || p.DateCreated.Month != date.Month || p.DateCreated.Day != date.Day))
    {
        return false;
    }
    return slug.Equals(Utils.RemoveIllegalCharacters(p.Slug), StringComparison.OrdinalIgnoreCase);
});

 

Days are now mandatory in the URL rewrite to lead to a valid post.  Our old links that were using the yyyy/mm pattern are now returning and error page, and without installing Elmah or double-checking links, I would probably not have noticed. .

The RelativeLink property of the class Post was changed at svn revision 8906 to change the pattern from yyyy/mm to yyyy/mm/dd.  This in itself was not a problem if the old links continued to work.  But with this new change to the UrlRewrite class, the legacy format no longer works.

I changed the code manually to fix our problem, but this might affect other BlogEngine.NET users as well.  If you have a pretty old blog where people link to your old blog posts, then you probably are affected.

After some investigation, this bug was introduced while fixing Bug 9212.

I made a temporary patch for those of you who run BlogEngine.NET 1.6 and are experiencing the same issue.

I changed the code in UrlRewrite to search posts a second time but ignoring days in the date if it didn’t find the post in the first search.  Here is my code:

var predicate = new Func<bool, Predicate<Post>>(includeDays =>
{
    return new Predicate<Post>(
        p =>
        {
            if (date != DateTime.MinValue &&
                (p.DateCreated.Year != date.Year || p.DateCreated.Month != date.Month || (p.DateCreated.Day != date.Day && includeDays)))
                    {
                        return false;
                    }
                    return slug.Equals(Utils.RemoveIllegalCharacters(p.Slug), StringComparison.OrdinalIgnoreCase);
                }
        );
});
 
// Search all post and include days in the search
// A valid link would look like this
// http://blog.com/post/2010/02/10/slug.aspx
Post post = Post.Posts.Find(predicate(true));
 
// We can't find this post, try to find it but ignore days in the path
// http://blog.com/post/2010/02/slug.aspx
// Some older blogengine.net site used this link pattern
// We want to preserve links to those sites.
if (post == null)
    post = Post.Posts.Find(predicate(false));

 

BlogEngine.NET developers are aware of this bug, but in the meantime, you can just drop this new version of BlogEngine.Core.dll in your bin folder to temporary fix the problem if you are using version 1.6 of BlogEngine.NET.

I highly recommend installing Elmah on your BlogEngine.NET to discover errors like these!

Download BlogEngine.NET 1.6 Binary Patch (drop in your bin folder)

kick it on DotNetKicks.com

Shout it