ASP.Net MVC RouteData and arrays ASP.Net MVC的RouteData和数组
ASP.Net MVC RouteData and arrays ASP.Net MVC的RouteData和数组
如果我有一个像这样的Action:
public ActionResult DoStuff(Liststuff) { ... ViewData["stuff"] = stuff; ... return View(); }
我可以通过以下URL访问它:
http://mymvcapp.com/controller/DoStuff?stuff=hello&stuff=world&stuff=foo&stuff=bar
但是在我的ViewPage中,我有这段代码:
<%= Html.ActionLink("点击这里", "DoMoreStuff", "MoreStuffController", new { stuff = ViewData["stuff"] }, null) %>
不幸的是,MVC并不聪明到足以识别该操作接受一个数组,并展开列表以形成正确的URL路由。相反,它只是对对象执行.ToString(),在List的情况下只会列出数据类型。
当目标Action的参数之一是数组或列表时,有办法让Html.ActionLink生成正确的URL吗?
-- 编辑 --
正如Josh在下面指出的那样,ViewData["stuff"]只是一个对象。我试图简化问题,但却引发了一个不相关的错误!我实际上正在使用一个专用的ViewPage
<%= Html.ActionLink("点击这里", "DoMoreStuff", "MoreStuffController", new { stuff = ViewData.Model.Stuff }, null) %>
其中ViewData.Model.Stuff的类型为List。
在ASP.Net MVC中,我们经常需要使用路由数据(RouteData)来传递参数。然而,当我们尝试将数组作为路由数据的值传递时,会遇到一些问题。这篇文章将讨论这个问题的原因以及一个解决方法。
问题的原因在于,当我们将数组作为路由数据的值传递时,ASP.Net MVC并不会正确地处理它。相反,它会将数组作为一个整体来处理,而不是将数组中的每个元素作为单独的值处理。这导致我们无法在路由中正确地获取数组中的每个元素。
为了解决这个问题,我们可以使用一个名为"FixListRouteDataValues"的方法。这个方法接受一个RouteValueDictionary对象作为参数,并返回一个修正后的RouteValueDictionary对象。在这个方法中,我们遍历传入的RouteValueDictionary对象,并检查每个值是否是一个数组。如果是数组,我们将数组中的每个元素都添加到新的RouteValueDictionary对象中,并使用"[index]"来给每个元素命名,以便在路由中正确地获取每个元素。如果不是数组,我们直接将键值对添加到新的RouteValueDictionary对象中。
使用这个方法的好处是,我们可以在任何需要使用带有数组的路由数据的扩展方法中使用它。通过调用这个方法,我们可以确保在路由中正确地传递和获取数组的每个元素。
不幸的是,这个解决方法在MVC3中仍然需要使用。这意味着,即使我们使用了最新的MVC版本,我们仍然需要手动修复路由数据中的数组值。
总结起来,当我们尝试在ASP.Net MVC中使用数组作为路由数据的值时,会遇到一些问题。为了解决这个问题,我们可以使用一个名为"FixListRouteDataValues"的方法,通过遍历路由数据并修正数组的值,来确保在路由中正确地传递和获取数组的每个元素。这个解决方法在MVC3中仍然需要使用。
问题的原因是使用ASP.Net MVC中的RouteData和数组时,通过在routevalues后面添加数组索引的方式,无法正确地生成期望的查询字符串。解决方法是对生成的URL进行URL编码。
具体的解决方法如下:
RouteValueDictionary rv = new RouteValueDictionary(); rv.Add("test[0]", val1); rv.Add("test[1]", val2);
上述代码会生成一个包含数组索引的查询字符串,例如`test=val1&test=val2`。然而,这种方式并不能达到预期的效果。
实际上,生成的URL是正确的,只是被进行了URL编码。因此,解决方法是对生成的URL进行URL解码。
感谢提供问题的人的建议,但是这种方法并不能解决问题。
ASP.Net MVC RouteData and arrays
在ASP.Net MVC中,使用RouteData和数组的时候可能会遇到一些问题。下面的代码是一个自定义HtmlHelper方法,用于生成带有数组参数的ActionLink链接。
public static string ActionLinkWithList(this HtmlHelper helper, string text, string action, string controller, object routeData, object htmlAttributes) { var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); string href = urlHelper.Action(action, controller); if (routeData != null) { RouteValueDictionary rv = new RouteValueDictionary(routeData); ListurlParameters = new List (); foreach (var key in rv.Keys) { object value = rv[key]; if (value is IEnumerable && !(value is string)) { int i = 0; foreach (object val in (IEnumerable)value) { urlParameters.Add(string.Format("{0}[{2}]={1}", key, val, i)); ++i; } } else if (value != null) { urlParameters.Add(string.Format("{0}={1}", key, value)); } } string paramString = string.Join("&", urlParameters.ToArray()); if (!string.IsNullOrEmpty(paramString)) { href += "?" + paramString; } } TagBuilder builder = new TagBuilder("a"); builder.Attributes.Add("href", href); builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); builder.SetInnerText(text); return builder.ToString(TagRenderMode.Normal); }
这段代码中,我们使用了RouteData来生成URL,并且处理了参数值为数组的情况。在遍历RouteData的时候,如果值是一个数组且不是字符串类型,我们将其拆分成多个参数,并按照特定的格式拼接成查询字符串。
这个方法的实现是为了解决在使用ActionLink生成URL时,如果参数值是数组,会出现无法正确处理的问题。由于默认情况下,ActionLink方法只能处理简单类型的参数值,对于数组等复杂类型的参数值,需要自己手动处理。
使用这个自定义的HtmlHelper方法,我们可以生成带有数组参数的ActionLink链接,解决了原生的ActionLink方法无法处理这种情况的问题。
在使用这个方法的时候,需要注意参数值的类型。如果参数值是数组类型,可以正常处理;如果参数值是字符串类型,可能会产生错误的结果。可以通过检查参数值是否实现了IList接口来解决这个问题,或者明确排除字符串类型。
另外,需要注意的是,这个方法将所有的路由参数都处理成了查询字符串参数,而原生的ActionLink方法会根据全局配置的路由规则来格式化路由参数,以支持REST风格的路由。如果需要保留原有的路由参数格式,可以在处理完数组参数后,将剩余的路由参数再传递给原生的ActionLink方法。
在使用这个方法的时候,还需要注意返回类型。由于方法返回的是一个字符串,如果直接将其插入到页面中,可能会存在安全性问题。可以将返回类型改为MvcHtmlString类型,确保输出的内容是安全的。
总之,通过自定义HtmlHelper方法,我们可以解决ASP.Net MVC中处理RouteData和数组参数的问题。这个方法可以处理数组参数,并将其拆分成多个查询字符串参数,生成带有数组参数的ActionLink链接。