The old version of Html.ImageActionLink had a serious flaw - I had to resolve to replacing parts of the generated link after the fact in order to get non html encoded information in there. That obviously creates, though not really probable in this specific case, the problem of unwanted replacement is possible.

So I learnt about UrlHelper and generate the whole MvcHtmlString in one go, without falling back on replacing stuff.

C#:
  1. public static MvcHtmlString ImageActionLink(
  2.     this HtmlHelper helper,
  3.     string imageUrl,
  4.     string altText,
  5.     string actionName,
  6.     string controllerName,
  7.     object routeValues,
  8.     object linkHtmlAttributes,
  9.     object imgHtmlAttributes)
  10. {
  11.     var linkAttributes = AnonymousObjectToKeyValue(linkHtmlAttributes);
  12.     var imgAttributes = AnonymousObjectToKeyValue(imgHtmlAttributes);
  13.  
  14.     var imgBuilder = new TagBuilder("img");
  15.  
  16.     imgBuilder.MergeAttribute("src", imageUrl);
  17.     imgBuilder.MergeAttribute("alt", altText);
  18.     imgBuilder.MergeAttributes(imgAttributes, true);
  19.  
  20.     var urlHelper = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection);
  21.  
  22.     var linkBuilder = new TagBuilder("a");
  23.  
  24.     linkBuilder.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
  25.     linkBuilder.MergeAttributes(linkAttributes, true);
  26.  
  27.     var text = linkBuilder.ToString(TagRenderMode.StartTag);
  28.     text += imgBuilder.ToString(TagRenderMode.SelfClosing);
  29.     text += linkBuilder.ToString(TagRenderMode.EndTag);
  30.  
  31.     return MvcHtmlString.Create(text);
  32. }
  33.  
  34. private static Dictionary<string, object> AnonymousObjectToKeyValue(object anonymousObject)
  35. {
  36.     var dictionary = new Dictionary<string, object>();
  37.  
  38.     if (anonymousObject != null)
  39.     {
  40.         foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
  41.         {
  42.             dictionary.Add(propertyDescriptor.Name, propertyDescriptor.GetValue(anonymousObject));
  43.         }
  44.     }
  45.  
  46.     return dictionary;
  47. }

The interface of the method is exactly the same so I can still use this version to create an image that is an actionlink in razor like this:

XML:
  1. @Html.ImageActionLink(
  2.    Url.Content("~/Content/Images/" + url),
  3.    alt,
  4.    "Details",
  5.    "Calender",
  6.    new { area = "", day = Model.Date.Day, month = Model.Date.Month, year = Model.Date.Year },
  7.    new { @class = "SelectDay", onClick = string.Format("DoCallbackBookingDetails({0},{1},{2}); return false;", Model.Date.Day, Model.Date.Month, Model.Date.Year) },
  8.    new { style = "border: 0px;" })