How to build a RouteValueDictionary when a route has multiple values?

I am creating a reusable method that inspects my model and automatically builds URLs (via ActionLink) for paging. One of the properties on my model is a string[] (for a multi-select pick list) which is entirely valid. An example of the URL would be: .

However, as the name of the type implies, RouteValueDictionary implements IDictionary so it can't accept the same key more than once.

var modelType = model.GetType();
var routeProperties = modelType.GetProperties().Where(p => Attribute.IsDefined(p, typeof(PagingRouteProperty)));
if (routeProperties != null && routeProperties.Count() > 0) { foreach (var routeProperty in routeProperties) { if (routeProperty.PropertyType == typeof(String)) { routeDictionary.Add(routeProperty.Name, routeProperty.GetValue(model, null)); } if (routeProperty.PropertyType == typeof(Boolean?)) { var value = (Boolean?)routeProperty.GetValue(model, null); routeDictionary.Add(routeProperty.Name, value.ToString()); } //The problem occurs here! if (routeProperty.PropertyType == typeof(string[])) { var value = (string[])routeProperty.GetValue(model); foreach (var v in value) { routeDictionary.Add(routeProperty.Name, v); } } }
//Eventually used here
var firstPageRouteDictionary = new RouteValueDictionary(routeDictionary);
firstPageRouteDictionary.Add("page", 1);
firstPageListItem.InnerHtml = htmlHelper.ActionLink("«", action, controller, firstPageRouteDictionary, null).ToHtmlString();

What can I use to build the routes when a key is needed more than once?

2

2 Answers

Just try to imagine how the link would look and it should make sense

new RouteValueDictionary { { "name[0]", "Justin" }, { "name[1]", "John" }, { "name[2]", "Sally" } }

which will generate the following query string

Encoded

?name%5B0%5D=Justin&name%5B1%5D=John&name%5B3%5D=Sally

Decoded

?name[0]=Justin&name[1]=John&name[3]=Sally

You just need to specify the property name along with the indexer as the Key:

if (routeProperty.PropertyType == typeof(string[])) { var value = (string[])routeProperty.GetValue(model); for (var i = 0; i < value.Length; i++) { var k = String.Format("{0}[{1}]", routeProperty.Name, i); routeDictionary.Add(k, value[i]); }
}

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like