ASP.Net MVC Dictionary Url Route

date_range  17 May 2014

ASP.Net
.Net Development
Tutorial

I recently needed a way of passing a dictionary to a Http GET method on a controller and managed to cobble something together that solves the problem although not in a particularly perfect manner, but still, I felt it warranted sharing.

First off, this problem doesn’t need to be solved for POST requests as the MVC model binder does a great job of this as long as you follow certain rules.  It can decipher dictionaries and lists by passing it indexed properties in the post data.  For example if we wanted to filter some products of a certain category we would send:

productCategoryToFilter = screen
filters[0].Key = colour
filters[0].Value = black
filters[1].Key = manufacturer
filters[1].Value = samsung

Here’s a blog post by Scott Hanselman that goes into more detail: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx.

Now lets say we wanted to do the same thing but with a GET request we would probably want a URL that looks a bit like this:

/products/screen/filter/colour/black/manufacturer/samsung

The controller would probably look a little like this:

Now as it stands the default MVC route handler isn’t going to know how to put our key value pairs together so we need to create one that will do that for us.

Now this is dirty as hell and would love some feedback on how to clean it up, especially the result of Regex.Split having to be filtered (my regex is top of the class) but does do the job.  We can quite safely assume that we are only going to be passing primitive types into a URL so the use of Covert.ChangeType is justified to make the route handler generic.

To then use the handler and set up our example route we add a route to our RouteCollection like so:

We use {filters} ( meaning wildcard) so that we can have an infinite number of key value pairs.

As I said before this isn’t fool proof and when using this technique you will have to be especially carful to url encode you keys and values to not include / otherwise the values will get out of sync.

comments powered by Disqus

chevron_left Archive