将数组传递给RouteValues并让它呈现模型binder-friendly url

时间:2011-12-05 19:57:53

标签: asp.net-mvc-3 asp.net-mvc-routing

RouteValueDicitonary或匿名对象传递给@ Url.Action方法(或其任何类似物)时,有没有办法正确传入集合对象或IEnumerable以便它生成一个与默认模型绑定器兼容的URL?

例如,假设我有这样的动作:

public ActionResult Index(ICollection<int> ids)
  {
    ...do something
  }

在我的模板中我做了类似的事情:

@Url.Action("Index", routeValues:new int[]{1,2,3})

目标是拥有这样的网址输出:

... /index?ids=1&ids=2&ids=3

但url输出实际上是这样的:

... /index?ids=System.Int[]

我假设目前没有这方面的支持。如果没有,那么在MVC的哪个部分我需要创建一个自定义处理程序或其他什么来覆盖这个默认功能?

3 个答案:

答案 0 :(得分:11)

不幸的是,目前没有允许您生成此类网址的现有帮助程序。因此,一种可能性是手动完成:

@(Url.Action("Index") + "?" + string.Join("&", new int[] { 1, 2, 3 }.Select(x => "ids=" + x)))

或编写扩展方法来封装逻辑:

@Url.ActionWithIds("Index", new int[] { 1, 2, 3 })

由于这些是整数,我们不需要url编码,但是如果你想对一组字符串做同样的事情,那么值应该正确地进行url编码。

答案 1 :(得分:2)

使用模型绑定语法将数组的每个元素传递给RouteValueDictionary以进行往返。

int i = 0;
var temprvd = arr.ToDictionary(m => String.Format("name[{0}]", i++), m => (object) m);
@Url.Action("index", new RouteValueDictionary(temprvd));

或连接到现有的路线值字典。

将值转换为object(如上所示),以确保使用正确的RouteValueDictionary构造函数重载。

答案 2 :(得分:1)

要使用默认的模型绑定器,您最终应该使用以下内容:

?ids=1&ids=2&ids=3

你可以返回一个名为HttpValueCollection的私有集合,即使文档说它是使用ParseQueryString实用程序的NameValueCollection。 然后手动添加密钥,HttpValueCollection为您执行编码。 然后手动附加QueryString:

var qs = HttpUtility.ParseQueryString(""); 
new List<int> { 1, 2, 3, 4, 5 }.ForEach(x => qs.Add("ids", x.ToString()));

@Url.Action("Index")?@qs