Come si accetta un array come parametro di azione del controller ASP.NET MVC?

Ho un controller ASP.net MVC chiamato Designs che ha un’azione con la seguente firma:

 public ActionResult Multiple(int[] ids) 

Tuttavia, quando provo a navigare su questa azione usando l’url:

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

Il parametro ids è sempre nullo. C’è un modo per convincere MVC a convertire il parametro di query ?ids= URL in un array per l’azione? Ho visto parlare di usare un filtro azione ma, per quanto posso dire, funzionerà solo per i POST in cui l’array viene passato nei dati della richiesta piuttosto che nell’URL stesso.

Il raccoglitore modello predefinito prevede questo URL:

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

per vincolare correttamente a:

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

E se vuoi che funzioni con valori separati da virgole, puoi scrivere un modello personalizzato:

 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(); } } 

e quindi è ansible applicare questo modello di binder a un particolare argomento di azione:

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

o applicarlo globalmente a tutti i parametri dell’intero array in Application_Start in Global.asax :

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

e ora l’azione del tuo controller potrebbe essere simile a questa:

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

Puoi anche utilizzare questo formato URL e ASP.NET MVC farà tutto per te. Ma ricorda di applicare la codifica URL.

 ?param1[0]=3344&param1[1]=2222 

Per estendere la risposta di Darin Dimitrov , qualcosa che puoi farla franca è accettare una semplice string nel tuo parametro URL e convertirla in un array tu stesso:

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

Se si verifica un errore di analisi mentre si esegue questa operazione (poiché qualcuno ha trasmesso un array non valido), è ansible far sì che il gestore di eccezioni restituisca un errore 400 Bad Request valida anziché l’errore 404 Not Found predefinito più ostile che MVC restituisce quando un endpoint è non trovato.

Non so da dove provenisse la stringa dell’URL di Groky, ma ho avuto lo stesso problema con alcuni javascript che chiamavano il mio controller / azione. Crea un URL di null , 1 o molti “ID” da un elenco a selezione multipla (che è unico per la soluzione che condividerò).

Ho copiato / incollato il modello personalizzato di Darin e decorato la mia azione / parametro, ma non ha funzionato. Ho ancora gli int[] ids valore null . Anche nel caso “sicuro” in cui effettivamente avevo molti ID.

Ho finito per cambiare il javascript per produrre un array di parametri amichevole ASP.NET MVC come

 ?ids=1&ids=2 

Dovevo fare alcune cose stupide, però

 ids || [] #=> if null, get an empty array [ids || []] #=> if a single item, wrap it in an array [].concat.apply([], ...) #=> in case I wrapped an array, flatten it 

Quindi, il blocco completo era

 ids = [].concat.apply([], [ids || []]) id_parameter = 'ids=' + ids.join('&ids=') 

È disordinato, ma è la prima volta che ho dovuto hackerare questo in javascript.