RouteValueDictionary and why we need Hash Literals

When working with ASP.NET MVC you will find quite a lot of code that needs key value pairs, especially for routing and providing html attributes, and in most of these places you will see a trend whereby no Dictionary type is created but instead an anonymous type is used:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }

So how can it take our anonymous type and create a dictionary from it? Well the object that does the work resides in System.Web.Routing and is called RouteValueDictionary (I think this should be called something like AnonymousTypeDictionary and placed somewhere else as it doesn’t really have anything to do with routing and is used in other sections), this object implements IDictionary<string, object> and has an overloaded constructor that takes a plain object type, it then uses reflection to grab the properties associated with the object and uses the property name as the key and the property value as the value.

So when any of the ASP.NET MVC objects want to create a key value pair they simply pass the anonymous type to the RouteValueDictionary object’s constructor:

// routeValues and htmlAttributes come in as object type.

return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));

And voila instant IDictionary<string, object>!

So if this works what’s the problem… well in IMO it’s hack to get round the issue that C# doesn’t have support for hash literals and it would seem I’m not alone, it suffers from a few problems:

  1. Because it uses anonymous types this means the parameter to the method has to be of type object, and from an API point of view that gives us nothing to go as to what needs to be passed in.
  2. It uses reflection to build the key value pairs which takes a performance hit.

For instance take Boo, we could write the following:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { "controller" = "Home", "action" = "Index", "id" = "" }

Or by using the open compiler wizardry:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { controller = "Home", action = "Index", id = "" }

Maybe this is asking too much from the compiler and this is as close as were going to get but that would be a shame given the problems above this approach suffers from.

Advertisements

4 thoughts on “RouteValueDictionary and why we need Hash Literals

  1. Pingback: ASP.NET MVC Archived Blog Posts, Page 1
  2. Pingback: Extending the ASP.NET HtmlHelper « Journal of a software dev
  3. Pingback: Extending the ASP.NET MVC HtmlHelper « Journal of a software dev

Comments are closed.