如何接受数组作为ASP.NET MVC控制器操作参数?


84

我有一个ASP.net MVC控制器Designs,该控制器具有以下签名的操作:

public ActionResult Multiple(int[] ids)

但是,当我尝试使用url导航到此操作时:

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

ids参数始终为空。有什么办法让MVC将?ids=URL查询参数转换为操作数组?我已经看到过使用动作过滤器的讨论,但据我所知,这仅适用于POST在请求数据中而不是在URL本身中传递数组的情况。

Answers:


150

默认模型联编程序期望使用以下网址:

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

为了成功绑定到:

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

而且,如果您希望将其与逗号分隔的值一起使用,则可以编写自定义模型绑定程序:

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

然后可以将此模型绑定程序应用于特定的action参数:

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

或全局应用到所有的整数数组参数Application_StartGlobal.asax

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

现在您的控制器动作可能如下所示:

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

2
我不见了[FromUri]public ActionResult Multiple([FromUri]int[] ids) {} (GET)
C0d1ngJammer

1
@Darin有没有一种方法可以全局应用自定义绑定,而只是忽略特定操作?我找不到一种方法:stackoverflow.com/questions/45379040/…–
akd

15

为了扩展Darin Dimitrov的答案可以避免的事情是接受stringURL参数中的简单参数,然后将其自己转换为数组:

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

如果在执行此操作时遇到解析错误(因为有人向您传递了格式错误的数组),则可以使异常处理程序返回400 Bad Request错误,而不是404 Not FoundMVC在找不到端点时返回的默认,更不友好的错误。


9

您也可以使用此URL格式,ASP.NET MVC将为您做所有事情。但是,请记住应用URL编码。

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

6

我不知道Groky的URL字符串是从哪里来的,但是我遇到了一些JavaScript调用控制器/动作的问题。它将null从多选列表中建立一个URL ,1或许多“ ID”(这是我要共享的解决方案所独有的)。

我复制/粘贴了Darin的自定义模型活页夹,并修饰了我的动作/参数,但这没有用。我仍然很null珍惜int[] ids。即使在“安全”情况下,我实际上确实有许多ID。

我最终更改了JavaScript,以生成一个ASP.NET MVC友好参数数组,例如

?ids=1&ids=2

我不得不做一些愚蠢的事情

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

因此,整块是

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

杂乱无章,但这是我第一次不得不在javascript中进行此类黑客攻击。


1
只是想知道最后一句话中“第一次”之前是否缺少“ not”。否则,很幸运!
DCShannon

1
@DCShannon:哈哈,我明白你的意思了!但是,这是我第一次。我不确定这种情况是否正常,或者我是否会过度。
Anthony Mastrean 2015年

0

.Net核心答案

对于最近来这里的用户,您可以在.Net Core中执行以下操作:

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

和:

public ActionResult Multiple([FromQuery] int[] ids)
{
    ...
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.