ASP.NET MVC – 在Html.ActionLink(…)中传递数组对象作为路由值

我有一个方法返回一个数组(string[]),我试图将这个string数组传递到一个动作链接,以便它将创build一个查询string类似于:

/Controller/Action?str=val1&str=val2&str=val3...etc 

但是,当我通过新的{str = GetStringArray()}我得到以下url:

 /Controller/Action?str=System.String%5B%5D 

所以基本上它是我的string[]和运行.ToString()上获取值。

有任何想法吗? 谢谢!

尝试创build一个保存你的值的RouteValueDictionary。 您必须为每个条目提供不同的密钥。

 <% var rv = new RouteValueDictionary(); var strings = GetStringArray(); for (int i = 0; i < strings.Length; ++i) { rv["str[" + i + "]"] = strings[i]; } %> <%= Html.ActionLink( "Link", "Action", "Controller", rv, null ) %> 

会给你一个链接

 <a href='/Controller/Action?str=val0&str=val1&...'>Link</a> 

编辑 :MVC2改变了ValueProvider接口,使我原来的回答过时。 您应该使用具有string数组的模型作为属性。

 public class Model { public string Str[] { get; set; } } 

然后,模型联编程序将使用您在URL中传递的值填充模型。

 public ActionResult Action( Model model ) { var str0 = model.Str[0]; } 

这真的让我非常恼火,所以我从Scott Hanselman那里得到了灵感,我写了下面的(stream利的)扩展方法:

 public static RedirectToRouteResult WithRouteValue( this RedirectToRouteResult result, string key, object value) { if (value == null) throw new ArgumentException("value cannot be null"); result.RouteValues.Add(key, value); return result; } public static RedirectToRouteResult WithRouteValue<T>( this RedirectToRouteResult result, string key, IEnumerable<T> values) { if (result.RouteValues.Keys.Any(k => k.StartsWith(key + "["))) throw new ArgumentException("Key already exists in collection"); if (values == null) throw new ArgumentNullException("values cannot be null"); var valuesList = values.ToList(); for (int i = 0; i < valuesList.Count; i++) { result.RouteValues.Add(String.Format("{0}[{1}]", key, i), valuesList[i]); } return result; } 

像这样调用:

 return this.RedirectToAction("Index", "Home") .WithRouteValue("id", 1) .WithRouteValue("list", new[] { 1, 2, 3 }); 

刚才想到的另一个解决scheme是:

 string url = "/Controller/Action?iVal=5&str=" + string.Join("&str=", strArray); 

这是肮脏的,你应该在使用它之前testing它,但它应该工作。 希望这可以帮助。

有一个名为Unbinder的库,您可以使用它来将复杂的对象插入到路由/ URL中。

它是这样工作的:

 using Unbound; Unbinder u = new Unbinder(); string url = Url.RouteUrl("routeName", new RouteValueDictionary(u.Unbind(YourComplexObject))); 

这是一个HelperExtension求解数组和IEnumerable属性的麻烦:

 public static class AjaxHelperExtensions { public static MvcHtmlString ActionLinkWithCollectionModel(this AjaxHelper ajaxHelper, string linkText, string actionName, object model, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) { var rv = new RouteValueDictionary(); foreach (var property in model.GetType().GetProperties()) { if (typeof(ICollection).IsAssignableFrom(property.PropertyType)) { var s = ((IEnumerable<object>)property.GetValue(model)); if (s != null && s.Any()) { var values = s.Select(p => p.ToString()).Where(p => !string.IsNullOrEmpty(p)).ToList(); for (var i = 0; i < values.Count(); i++) rv.Add(string.Concat(property.Name, "[", i, "]"), values[i]); } } else { var value = property.GetGetMethod().Invoke(model, null) == null ? "" : property.GetGetMethod().Invoke(model, null).ToString(); if (!string.IsNullOrEmpty(value)) rv.Add(property.Name, value); } } return System.Web.Mvc.Ajax.AjaxExtensions.ActionLink(ajaxHelper, linkText, actionName, rv, ajaxOptions, htmlAttributes); } } 

我会使用POST的数组。 除了丑陋和滥用GET之外,您可能会冒用尽URL空间(不pipe信不信)。

假设2000字节的限制 。 查询string开销(&str =)将您减less到约300字节的实际数据(假设其余的url为0字节)。