When passing a RouteValueDicitonary
or anonymous object into a @Url.Action method (or any of its analogs), is there a way to properly pass in a collection object or IEnumerable
so that it would generate a url that would be compatible with the default model binder?
For example, say I have an action like this:
public ActionResult Index(ICollection<int> ids)
{
...do something
}
and in my template I do something like this:
@Url.Action("Index", routeValues:new int[]{1,2,3})
the goal is to have a url output like this:
... /index?ids=1&ids=2&ids=3
but the url output is actually something like this:
... /index?ids=System.Int[]
I'm assuming there is no support for this currently. If not, then at what part in MVC do I need to create a custom handler or whatever to override this default functionality?
Unfortunately currently there is no existing helper that will allow you to generate such url. So one possibility is to do it manually:
@(Url.Action("Index") + "?" + string.Join("&", new int[] { 1, 2, 3 }.Select(x => "ids=" + x)))
or write an extension method to encapsulate the logic:
@Url.ActionWithIds("Index", new int[] { 1, 2, 3 })
Since those are integers we don't need url encoding but if you want to do the same thing with a collection of strings the values should be properly url encoded.
Pass each element of the array to a RouteValueDictionary
using the model binding syntax for round trip purposes.
int i = 0;
var temprvd = arr.ToDictionary(m => String.Format("name[{0}]", i++), m => (object) m);
@Url.Action("index", new RouteValueDictionary(temprvd));
or concat on to an existing route value dictionary.
Cast the value to an object
(as shown above) to ensure the correct RouteValueDictionary
constructor overload is used.
For use the default model binder, you should end up with something like :
?ids=1&ids=2&ids=3
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 List<int> { 1, 2, 3, 4, 5 }.ForEach(x => qs.Add("ids", x.ToString()));
@Url.Action("Index")?@qs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With