asp.net mvc 3 - update - ¿Cómo acepto una matriz como un parámetro de acción del controlador ASP.NET MVC?
view mvc asp net (4)
El archivador de modelo predeterminado espera esta url:
http://localhost:54119/Designs/Multiple?ids=24041&ids=24117
para unirse exitosamente a:
public ActionResult Multiple(int[] ids)
{
...
}
Y si desea que esto funcione con valores separados por comas, puede escribir un archivador de modelo personalizado:
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();
}
}
y luego podría aplicar este encuadernador modelo a un argumento de acción particular:
public ActionResult Multiple([ModelBinder(typeof(IntArrayModelBinder))] int[] ids)
{
...
}
o aplicarlo globalmente a todos los parámetros de matriz de enteros en su Application_Start
en Global.asax
:
ModelBinders.Binders.Add(typeof(int[]), new IntArrayModelBinder());
y ahora su acción de controlador podría verse así:
public ActionResult Multiple(int[] ids)
{
...
}
Tengo un controlador MVC ASP.net llamado Designs
que tiene una acción con la siguiente firma:
public ActionResult Multiple(int[] ids)
Sin embargo, cuando trato de navegar a esta acción usando la url:
http://localhost:54119/Designs/Multiple?ids=24041,24117
El parámetro ids
siempre es nulo. ¿Hay alguna manera de hacer que MVC convierta el parámetro de consulta ?ids=
URL en una matriz para la acción? He visto hablar sobre el uso de un filtro de acción, pero hasta donde sé, eso solo funcionará para los POST donde el arreglo se pasa en los datos de solicitud en lugar de en la URL misma.
No sé de dónde venía la cadena URL de Groky, pero tuve el mismo problema con algunos javascript llamando a mi controlador / acción. Construiría una URL de null
, 1 o muchos "ID" de una lista de selección múltiple (que es exclusiva de la solución que voy a compartir).
Copié / pegué el encuadernador de modelo personalizado de Darin y decoré mi acción / parámetro, pero no funcionó. Todavía obtuve int[] ids
valuadas null
. Incluso en el caso "seguro" donde realmente tenía muchas identificaciones.
Terminé cambiando el javascript para producir una matriz de parámetros amigable de ASP.NET MVC como
?ids=1&ids=2
Aunque tuve que hacer algunas tonterías
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
Entonces, el bloque completo era
ids = [].concat.apply([], [ids || []])
id_parameter = ''ids='' + ids.join(''&ids='')
Es complicado, pero es la primera vez que tengo que hackear esto en javascript.
Para extender la respuesta de Darin Dimitrov , algo con lo que puedes salirte es aceptar una string
simple en tu parámetro de URL y convertirla en una matriz tú mismo:
public ActionResult Multiple(string ids){
int[] idsArray = ids.Split('','').Select(int.Parse).ToArray();
/* ...process results... */
}
Si obtiene un error de análisis al hacer esto (porque alguien le pasó una matriz con formato incorrecto), puede hacer que su controlador de excepción devuelva un error de 400 Bad Request
erróneas en lugar del error 404 Not Found
predeterminado más antipático que MVC devuelve cuando se encuentra un punto final extraviado.
También puede usar este formato de URL y ASP.NET MVC hará todo por usted. Pero recuerde aplicar la codificación URL.
?param1[0]=3344¶m1[1]=2222