views:

2302

answers:

2

I have a method that returns an array (string[]) and I'm trying to pass this array of strings into an Action Link so that it will create a query string similar to:

/Controller/Action?str=val1&str=val2&str=val3...etc

But when I pass new { str = GetStringArray() } I get the following url:

/Controller/Action?str=System.String%5B%5D

So basically it's taking my string[] and running .ToString() on it to get the value.

Any ideas? Thanks!

A: 

I'd use POST for an array. Aside from being ugly and an abuse of GET, you risk running out of URL space (believe it or not).

Assuming a 2000 byte limit. The query string overhead (&str=) reduces you to ~300 bytes of actual data (assuming the rest of the url is 0 bytes).

Greg Dean
+1  A: 

Try creating a RouteValueDictionary holding your values. You'll have to give each entry a different key.

<%  var rv = new RouteValueDictionary();
    var strings = GetStringArray();
    for (int i = 0; i < strings.Length; ++i)
    {
        rv["str[" + i + "]"] = strings[i];
    }
 %>

<%= Html.ActionLink( "Link", "Action", "Controller", rv, null ) %>

will give you a link like

<a href='/Controller/Action?str=val0&str=val1&...'>Link</a>

EDIT: MVC2 changed the ValueProvider interface to make my original answer obsolete. You should use a model with an array of strings as a property.

public class Model
{
    public string Str[] { get; set; }
}

Then the model binder will populate your model with the values that you pass in the URL.

public ActionResult Action( Model model )
{
    var str0 = model.Str[0];
}
tvanfosson
Just thought I'd mention that it looks like you've given another alternative to a similar question over here at: [ASP.Net MVC RouteData and arrays] (http://stackoverflow.com/questions/1752721/asp-net-mvc-routedata-and-arrays). Is there a way to link these two questions so that people can see both of your alternatives?
GuyIncognito
I think you just did. Actually this won't work any more. I'll update the action method to use a model.
tvanfosson
The model binding is not the issue. It seems MVC 2 still generates query strings like `?str=System.String%5B%5D` when a `RouteValueDictionary` value contains an array/list/etc. Still no way around that?
Crescent Fresh
@Crescent - are you sure you're using the signature that has both route values and html attributes?
tvanfosson
Crescent Fresh
@Crescent - sorry I misunderstood. The solution I propose adds each of the elements of the array individually to the RouteValueDictionary, avoiding the problem. The serializer iterates over the properties of the object adding them as key/value pairs to the dictionary internally. This is obviously **not** what you want for an array. See my other answer (quoted above by @Guy) for a helper extension that handles IEnumerables differently. Note that I don't use this -- typically I'll use post and Phil Haack's method of binding lists of objects.
tvanfosson