Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I accept an array as an ASP.NET MVC controller action parameter?

I have an ASP.net MVC controller called Designs that has an action with the following signature:

public ActionResult Multiple(int[] ids) 

However, when I try to navigate to this action using the url:

http://localhost:54119/Designs/Multiple?ids=24041,24117 

The ids parameter is always null. Is there any way to get MVC to convert the ?ids= URL query parameter into an array for the action? I've seen talk of using an action filter but as far as I can tell that will only work for POSTs where the array is passed in the request data rather than in the URL itself.

like image 938
Grokys Avatar asked Feb 29 '12 23:02

Grokys


People also ask

Can we have MVC controller with parameterized constructor?

Simply framework will fail to create those controllers object that have parameterized constructor. In that case we need to create controller objects by our self and inject controller parameters there.


2 Answers

The default model binder expects this url:

http://localhost:54119/Designs/Multiple?ids=24041&ids=24117 

in order to successfully bind to:

public ActionResult Multiple(int[] ids) {     ... } 

And if you want this to work with comma separated values you could write a custom model binder:

public class IntArrayModelBinder : DefaultModelBinder {     public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)     {         var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);         if (value == null || string.IsNullOrEmpty(value.AttemptedValue))         {             return null;         }          return value             .AttemptedValue             .Split(',')             .Select(int.Parse)             .ToArray();     } } 

and then you could apply this model binder to a particular action argument:

public ActionResult Multiple([ModelBinder(typeof(IntArrayModelBinder))] int[] ids) {     ... } 

or apply it globally to all integer array parameters in your Application_Start in Global.asax:

ModelBinders.Binders.Add(typeof(int[]), new IntArrayModelBinder()); 

and now your controller action might look like this:

public ActionResult Multiple(int[] ids) {     ... } 
like image 163
Darin Dimitrov Avatar answered Oct 13 '22 04:10

Darin Dimitrov


To extend on Darin Dimitrov's answer, something you can get away with is accepting a simple string in your URL parameter and converting it to an array yourself:

public ActionResult Multiple(string ids){   int[] idsArray = ids.Split(',').Select(int.Parse).ToArray();   /* ...process results... */ } 

If you get a parse error while doing this (because someone passed you a malformed array), you can cause your exception handler to return a 400 Bad Request error instead of the default, more unfriendly 404 Not Found error that MVC returns when an endpoint is not found.

like image 39
TheHans255 Avatar answered Oct 13 '22 06:10

TheHans255