我有一个名为 Designs
的 ASP.net MVC 控制器,它有一个带有以下签名的操作:
public ActionResult Multiple(int[] ids)
但是,当我尝试使用 url 导航到此操作时:
http://localhost:54119/Designs/Multiple?ids=24041,24117
ids
参数始终为空。有没有办法让 MVC 将 ?ids=
URL 查询参数转换为操作的数组?我已经看到有关使用操作过滤器的讨论,但据我所知,这仅适用于数组在请求数据中而不是在 URL 本身中传递的 POST。
默认模型绑定器需要此 url:
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();
}
}
然后您可以将此模型绑定器应用于特定的操作参数:
public ActionResult Multiple([ModelBinder(typeof(IntArrayModelBinder))] int[] ids)
{
...
}
或将其全局应用于 Global.asax
中 Application_Start
中的所有整数数组参数:
ModelBinders.Binders.Add(typeof(int[]), new IntArrayModelBinder());
现在您的控制器操作可能如下所示:
public ActionResult Multiple(int[] ids)
{
...
}
要在 Darin Dimitrov's answer 上进行扩展,您可以在 URL 参数中接受一个简单的 string
并自己将其转换为数组:
public ActionResult Multiple(string ids){
int[] idsArray = ids.Split(',').Select(int.Parse).ToArray();
/* ...process results... */
}
如果您在执行此操作时遇到解析错误(因为有人向您传递了格式错误的数组),您可能会导致您的异常处理程序返回一个 400 Bad Request
错误,而不是 MVC 在端点被返回时返回的默认的、更不友好的 404 Not Found
错误未找到。
您也可以使用这种 URL 格式,ASP.NET MVC 将为您完成所有工作。但是,请记住应用 URL 编码。
?param1[0]=3344¶m1[1]=2222
我不知道 Groky 的 URL 字符串是从哪里来的,但是我在调用我的控制器/动作的一些 javascript 时遇到了同样的问题。它会从多选列表中构建一个包含 null
、1 或许多“ID”的 URL(这是我要分享的解决方案所独有的)。
我复制/粘贴了 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 中像这样破解。
.Net 核心答案
对于最近来到这里的人,您可以在 .Net Core 中执行此操作:
http://localhost:54119/Designs/Multiple?ids=24041&ids=24117
和:
public ActionResult Multiple([FromQuery] int[] ids)
{
...
}
[FromUri]
。public ActionResult Multiple([FromUri]int[] ids) {}
(GET)