2009-04-04 37 views
38

Tôi có một phương thức trả về một mảng (chuỗi []) và tôi đang cố gắng chuyển mảng chuỗi này vào một Hành động liên kết để nó sẽ tạo ra một chuỗi truy vấn tương tự như:ASP.NET MVC - Vượt qua đối tượng mảng như một giá trị tuyến đường trong Html.ActionLink (...)

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

Nhưng khi tôi vượt qua mới {str = GetStringArray()} tôi nhận url sau:

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

vì vậy, về cơ bản nó lấy của tôi string [] và chạy .ToString() trên nó để lấy giá trị.

Bất kỳ ý tưởng nào? Cảm ơn!

+7

Bạn đã bao giờ nhận được một câu trả lời cho điều này? – reach4thelasers

Trả lời

-6

Tôi muốn sử dụng POST cho một mảng. Ngoài việc xấu và lạm dụng GET, bạn có nguy cơ hết dung lượng URL (tin hay không).

Giả sử 2000 byte limit. Giá trị chuỗi truy vấn (& str =) giảm bạn xuống ~ 300 byte dữ liệu thực tế (giả sử phần còn lại của url là 0 byte).

12

Thử tạo một RouteValueDictionary giữ các giá trị của bạn. Bạn sẽ phải cung cấp cho mỗi mục nhập một khóa khác nhau.

<% 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) %> 

sẽ cung cấp cho bạn một liên kết như

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

EDIT: MVC2 thay đổi giao diện ValueProvider để làm cho câu trả lời ban đầu của tôi trở nên lỗi thời. Bạn nên sử dụng một mô hình với một chuỗi các chuỗi như một thuộc tính.

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

Sau đó, trình kết nối mô hình sẽ điền mô hình của bạn với các giá trị bạn chuyển vào URL.

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

Chỉ cần nghĩ rằng tôi muốn đề cập rằng có vẻ như bạn đã đưa ra một giải pháp thay thế cho một câu hỏi tương tự ở đây tại: [ASP.Net MVC RouteData và mảng] (http://stackoverflow.com/questions/1752721/asp-net-mvc-routedata-and-arrays). Có cách nào để liên kết hai câu hỏi này để mọi người có thể thấy cả hai lựa chọn thay thế của bạn không? – GuyIncognito

+0

Tôi nghĩ bạn vừa làm. Trên thực tế điều này sẽ không làm việc nữa. Tôi sẽ cập nhật phương thức hành động để sử dụng một mô hình. – tvanfosson

+2

Mô hình ràng buộc không phải là vấn đề. Có vẻ như MVC 2 vẫn tạo ra các chuỗi truy vấn như '? Str = System.String% 5B% 5D' khi một giá trị' RouteValueDictionary' chứa một mảng/danh sách/etc. Vẫn không còn cách nào khác? –

2

Điều này thực sự khó chịu với tôi như vậy với inspiration from Scott Hanselman tôi đã viết như sau (thông thạo) phương pháp khuyến nông:

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; 
} 

Gọi như vậy:

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

Có một thư viện gọi Unbinder, mà bạn có thể sử dụng để chèn các đối tượng phức tạp vào các tuyến/url.

Nó hoạt động như thế này:

using Unbound; 

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

Một giải pháp mà chỉ lóe lên trong óc tôi:

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

Đây là bẩn và bạn nên kiểm tra nó trước khi sử dụng nó, nhưng nó phải làm việc vẫn. Hi vọng điêu nay co ich.

0

Đây là một HelperExtension giải quyết mảng và tính IEnumerable rắc rối:

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); 
    } 
} 
Các vấn đề liên quan