So you want to add some custom data to a html element to aid your JavaScript development and adding data values to custom attributes is a big no no so what do you do? This is where the new HTML5 data-* comes to your rescue.
The next issue is you can’t use the usual ActionLink method overloads on the html helper as you can’t pass in ‘-‘ into anonymous types because it is a c# reserved character for subtracting!
So on the train home this evening I came up with the following:
public static MvcHtmlString ActionLinkHtml5Data(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, object htmlDataAttributes)
{
if (string.IsNullOrEmpty(linkText))
{
throw new ArgumentException(string.Empty, "linkText");
}
var html = new RouteValueDictionary(htmlAttributes);
var data = new RouteValueDictionary(htmlDataAttributes);
foreach (var attributes in data)
{
html.Add(string.Format("data-{0}", attributes.Key), attributes.Value);
}
return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null, actionName, controllerName, new RouteValueDictionary(routeValues), html));
}
And to use it, you already know how to as its the same way as all the other ActionLink overrides which are already available out of the box with an additional parameter which works the same as the htmlattributes parameter.
<%: Html.ActionLinkHtml5Data(“link display”, "Action", "Controller", new { id = Model.Id }, new { @class="link" }, new { extra = “some extra info” }) %>
It worked like a dream.
The issue with the “-“ being reserved has had a work around in MVC 3 by using “_” and then programmatically changing that to being “-“ in the output. I’ve not looked at the implementation but I can’t see how this is much different to what I’ve already achieved simply above.
Please let me know your thoughts.