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?
22 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=SallyDecoded
?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]); }
}