14

I have an array of strings that I need to pass in a query string of Url.Action.

Url.Action("Index", "Resource", new { FormatIds = Model.FormatIDs})

Right now the link is showing up in my browser as System.String[] instead of a query string. Is it possible to have MVC do this automatically with model binding?

I need it to bind with my controller action like:

public ActionResult Index(string[] formatIDs)
user547794
  • 14,263
  • 36
  • 103
  • 152

3 Answers3

10

To get the list of string to automatically bind using the default binder, you will need to provide them as:

name=value&name=value2&name=value3

So you'll need to convert your list to something like:

Index?formatIDs=1&formatIDs=2&formatIDs=3
Andy T
  • 10,223
  • 5
  • 53
  • 95
  • +1 for the default model binder, that is the correct anwser. Very Nice Queti. – Felipe Oriani Dec 15 '12 at 00:43
  • 14
    This doesn't answer the question. He wants Url.Action to correctly output an array route value to the querystring. He is not asking how to bind such a value. – Sam Jun 30 '14 at 05:09
9

For use the default model binder, you should end up with something like :

Index?formatIDs=value1&formatIDs=value2&formatIDs=value3

you can returns a private collection named HttpValueCollection even the documentation says it's a NameValueCollection using the ParseQueryString utility. Then add the keys manually, HttpValueCollection do the encoding for you. And then just append the QueryString manually :

var qs = HttpUtility.ParseQueryString(""); 
new string[] { "value1", "value2", "value3" }.ToList().ForEach(x => qs.Add("formatIDs", x));

Url.Action("Index", "Resource")?@qs
Bart Calixto
  • 19,210
  • 11
  • 78
  • 114
  • 2
    Your suggestion works. But I wonder why it's still so strange and complex to send an array of strings from a razor View to a MVC controller action. – Sven May 30 '17 at 12:08
  • Because normally you should use a form HTML element with get verb and everything will be smooth and simple. – Bart Calixto May 30 '17 at 12:37
0

There is another way using the RouteValueDictionary with an array:

@{
   var parameters = new RouteValueDictionary();

   for (var i = 0; i < Model.CustomList.Count; ++i)
   {
       parameters.Add($"customListId[{i}]", Model.CustomList[i]);
   }
}

usage:

var url = '@Html.Raw(Url.Action("ControllerActioon", "Controller", parameters))';

Still not very elegant - but working.

Sven
  • 2,345
  • 2
  • 21
  • 43