ASP.Net MVC RouteData and arrays ASP.Net MVC RouteData and arrays arrays arrays

ASP.Net MVC RouteData and arrays


I'm thinking that a custom HtmlHelper would be in order.

 public static string ActionLinkWithList( this HtmlHelper helper, string text, string action, string controller, object routeData, object htmlAttributes ) {     var urlHelper = new UrlHelper( helper.ViewContext.RequestContext );     string href = urlHelper.Action( action, controller );     if (routeData != null)     {         RouteValueDictionary rv = new RouteValueDictionary( routeData );         List<string> urlParameters = new List<string>();         foreach (var key in rv.Keys)         {             object value = rv[key];             if (value is IEnumerable && !(value is string))             {                 int i = 0;                 foreach (object val in (IEnumerable)value)                 {                     urlParameters.Add( string.Format( "{0}[{2}]={1}", key, val, i ));                     ++i;                 }             }             else if (value != null)             {                 urlParameters.Add( string.Format( "{0}={1}", key, value ) );             }         }         string paramString = string.Join( "&", urlParameters.ToArray() ); // ToArray not needed in 4.0         if (!string.IsNullOrEmpty( paramString ))         {            href += "?" + paramString;         }     }     TagBuilder builder = new TagBuilder( "a" );     builder.Attributes.Add("href",href);     builder.MergeAttributes( new RouteValueDictionary( htmlAttributes ) );     builder.SetInnerText( text );     return builder.ToString( TagRenderMode.Normal );}


you can suffix your routevalues with an array index like so:

RouteValueDictionary rv = new RouteValueDictionary();rv.Add("test[0]", val1);rv.Add("test[1]", val2);

this will result in the querystring containing test=val1&test=val2

that might help ?


Combining both methods works nicely.

public static RouteValueDictionary FixListRouteDataValues(RouteValueDictionary routes){    var newRv = new RouteValueDictionary();    foreach (var key in routes.Keys)    {        object value = routes[key];        if (value is IEnumerable && !(value is string))        {            int index = 0;            foreach (string val in (IEnumerable)value)            {                newRv.Add(string.Format("{0}[{1}]", key, index), val);                index++;            }        }        else        {            newRv.Add(key, value);        }    }    return newRv;}

Then use this method in any extension method that requires routeValues with IEnumerable(s) in it.

Sadly, this workaround seams to be needed in MVC3 too.