asp.net-mvc ASP.NET MVC - 在 Html.ActionLink(...) 中将数组对象作为路由值传递
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/717690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET MVC - Pass array object as a route value within Html.ActionLink(...)
提问by
I have a method that returns an array (string[]) and I'm trying to pass this array of strings into an Action Link so that it will create a query string similar to:
我有一个返回数组 (string[]) 的方法,我试图将这个字符串数组传递到 Action Link 中,以便它创建一个类似于以下内容的查询字符串:
/Controller/Action?str=val1&str=val2&str=val3...etc
But when I pass new { str = GetStringArray() } I get the following url:
但是当我通过 new { str = GetStringArray() } 我得到以下网址:
/Controller/Action?str=System.String%5B%5D
So basically it's taking my string[] and running .ToString() on it to get the value.
所以基本上它使用我的 string[] 并在其上运行 .ToString() 来获取值。
Any ideas? Thanks!
有任何想法吗?谢谢!
回答by tvanfosson
Try creating a RouteValueDictionary holding your values. You'll have to give each entry a different key.
尝试创建一个 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 ) %>
will give you a link like
会给你一个链接
<a href='/Controller/Action?str=val0&str=val1&...'>Link</a>
EDIT: MVC2 changed the ValueProvider interface to make my original answer obsolete. You should use a model with an array of strings as a property.
编辑:MVC2 更改了 ValueProvider 接口以使我的原始答案过时。您应该使用带有字符串数组作为属性的模型。
public class Model
{
public string Str[] { get; set; }
}
Then the model binder will populate your model with the values that you pass in the URL.
然后模型绑定器将使用您在 URL 中传递的值填充您的模型。
public ActionResult Action( Model model )
{
var str0 = model.Str[0];
}
回答by dav_i
This really annoyed me so with inspiration from Scott HanselmanI wrote the following (fluent) extension method:
这真的让我很恼火,所以在 Scott Hanselman 的启发下,我编写了以下(流利的)扩展方法:
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;
}
Call like so:
像这样调用:
return this.RedirectToAction("Index", "Home")
.WithRouteValue("id", 1)
.WithRouteValue("list", new[] { 1, 2, 3 });
回答by Jenny O'Reilly
Another solution that just came to my mind:
我刚刚想到的另一个解决方案:
string url = "/Controller/Action?iVal=5&str=" + string.Join("&str=", strArray);
This is dirty and you should test it before using it, but it should work nevertheless. Hope this helps.
这很脏,您应该在使用之前对其进行测试,但它仍然可以工作。希望这可以帮助。
回答by Jenny O'Reilly
There is a library called Unbinder, which you can use to insert complex objects into routes/urls.
有一个名为Unbinder的库,您可以使用它来将复杂对象插入到路由/url 中。
It works like this:
它是这样工作的:
using Unbound;
Unbinder u = new Unbinder();
string url = Url.RouteUrl("routeName", new RouteValueDictionary(u.Unbind(YourComplexObject)));
回答by GGO
This is a HelperExtension solving array and IEnumerable properties troubles :
这是一个 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);
}
}
回答by Greg Dean
I'd use POST for an array. Aside from being ugly and an abuse of GET, you risk running out of URL space (believe it or not).
我将 POST 用于数组。除了丑陋和滥用 GET 之外,您还有可能用完 URL 空间(信不信由你)。
Assuming a 2000 byte limit. The query string overhead (&str=) reduces you to ~300 bytes of actual data (assuming the rest of the url is 0 bytes).
假设有2000 字节的限制。查询字符串开销 (&str=) 将您减少到大约 300 字节的实际数据(假设 url 的其余部分是 0 字节)。

