Journal of a software dev

April 11, 2009

RouteValueDictionary and why we need Hash Literals

Filed under: .net, c# — Tags: , — Michael Cromwell @ 12:26 pm

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.

3 Comments »

  1. [...] to VoteRouteValueDictionary and why we need Hash Literals (4/11/2009)Saturday, April 11, 2009 from Michael CromwellWhen working with ASP.NET MVC you will find quite a [...]

    Pingback by ASP.NET MVC Archived Blog Posts, Page 1 — April 13, 2009 @ 5:36 am

  2. [...] that I use the RouteValueDictionary object so that I can use the anonymous type to dictionary trick, the UrlHelper deals with returning the routed URL I just need to provide the controller and what [...]

    Pingback by Extending the ASP.NET HtmlHelper « Journal of a software dev — April 24, 2009 @ 9:14 pm

  3. [...] that I use the RouteValueDictionary object so that I can use the anonymous type to dictionary trick, the UrlHelper deals with returning the routed URL I just need to provide the controller and what [...]

    Pingback by Extending the ASP.NET MVC HtmlHelper « Journal of a software dev — April 24, 2009 @ 9:16 pm


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.