2010-08-10 28 views

Trả lời

7

Scott Hanselman có một hướng dẫn tuyệt vời để làm điều này here.

+2

Phil Haack có phiên bản cập nhật, với dự án tải xuống. http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx –

1

Chỉ cần các loại quyền của bộ sưu tập. Chính xác loại phụ thuộc vào phiên bản:

MVC1: public ActionResult DoSomething(int[] input)
MVC2: public ActionResult DoSomething(IList<int> input)

+0

Bạn có thể chuyển một 'Danh sách ' vào một phương thức hành động trong MVC 1. – DaveDev

-1
[ArrayOrListParameterAttribute("ids", ",")] 
public ActionResult Index(List<string> ids) 
{ 

} 
+0

Không có thuộc tính như vậy. Không phải trong .NET, và googled và không tìm thấy mã nguồn ở bất cứ đâu. – AaronLS

8

Bạn cần phải vượt qua chúng để hành động của bạn bằng cách thêm mỗi số nguyên để POST hoặc GET chuỗi truy vấn như sau:

myints=1&myints=4&myints=6 

sau đó, trong hành động của bạn, bạn sẽ có những hành động sau đây

public ActionResult Blah(List<int> myints) 

MVC sau đó sẽ điền danh sách với 1,4 và 6

Một điều cần lưu ý. Chuỗi truy vấn của bạn KHÔNG THỂ có dấu ngoặc trong đó. Đôi khi khi danh sách javascript được tạo thành chuỗi truy vấn của bạn sẽ trông giống như sau:

myints[]=1&myints[]=4&myints[]=6 

Điều này sẽ làm cho danh sách của bạn rỗng (hoặc có số không). Các dấu ngoặc không được ở đó cho MVC để ràng buộc mô hình của bạn một cách chính xác.

1

Nếu bạn đang cố gắng để gửi danh sách từ một số hạng mục giao diện (như, một bảng), bạn chỉ có thể thiết lập thuộc tính tên của họ trong HTML để: CollectionName [Index] ví dụ:

<input id="IntList_0_" name="IntList[0]" type="text" value="1" /> 
<input id="IntList_1_" name="IntList[1]" type="text" value="2" /> 

public ActionResult DoSomething(List<int> IntList) { 
} 

tham số IntList wil nhận được một danh sách có chứa 1 và 2 theo thứ tự mà

0

Cách sử dụng:

[ArrayOrListParameterAttribute("ids", ",")] 
public ActionResult Index(List<string> ids) 
{ 

} 

Ở đây mã cho ArrayOrListParameterAttribute

using System; 
using System.Web.Mvc; 
using System.Reflection; 
using System.Collections; 
using System.Collections.Generic; 

namespace MvcApplication1 
{ 
public class ArrayOrListParameterAttribute : ActionFilterAttribute 
{ 
    #region Properties 

    /// <summary> 
    /// Gets or sets the name of the list or array parameter. 
    /// </summary> 
    /// <value>The name of the list or array parameter.</value> 
    private string ListOrArrayParameterName { get; set; } 

    /// <summary> 
    /// Gets or sets the separator. 
    /// </summary> 
    /// <value>The separator.</value> 
    private string Separator { get; set; } 

    #endregion 

    #region Constructors 

    /// <summary> 
    /// Initializes a new instance of the <see cref="ArrayOrListParameterAttribute"/> class. 
    /// </summary> 
    /// <param name="listOrArrayParameterName">Name of the list or array parameter.</param> 
    public ArrayOrListParameterAttribute(string listOrArrayParameterName) : this(listOrArrayParameterName, ",") 
    { 

    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="ArrayOrListParameterAttribute"/> class. 
    /// </summary> 
    /// <param name="listOrArrayParameterName">Name of the list or array parameter.</param> 
    /// <param name="separator">The separator.</param> 
    public ArrayOrListParameterAttribute(string listOrArrayParameterName, string separator) 
    { 
     ListOrArrayParameterName = listOrArrayParameterName; 
     Separator = separator; 
    } 

    #endregion 

    #region Public Methods 

    /// <summary> 
    /// Called when [action executing]. 
    /// </summary> 
    /// <param name="filterContext">The filter context.</param> 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     string separatedValues = filterContext.RouteData.GetRequiredString(ListOrArrayParameterName); 
     ParameterInfo[] parameters = filterContext.ActionMethod.GetParameters(); 

     ParameterInfo searchedParameter = Array.Find(parameters, parameter => parameter.Name == ListOrArrayParameterName); 

     if (searchedParameter == null) 
      throw new InvalidOperationException(string.Format("Could not find Parameter '{0}' in action method '{1}'", ListOrArrayParameterName, filterContext.ActionMethod.Name)); 

     Type arrayOrGenericListType = searchedParameter.ParameterType; 

     if (!IsTypeArrayOrIList(arrayOrGenericListType)) 
      throw new ArgumentException("arrayOrIListType is not an array or a type implementing Ilist or IList<>: " + arrayOrGenericListType); 

     filterContext.ActionParameters[ListOrArrayParameterName] = GetArrayOrGenericListInstance(arrayOrGenericListType, separatedValues, Separator); 

     base.OnActionExecuting(filterContext); 
    } 

    #endregion 

    #region Non Public Methods 

    private static bool IsTypeArrayOrIList(Type type) 
    { 
     if (type.IsArray) 
      return true; 

     return (Array.Exists(type.GetInterfaces(), x => x == typeof(IList) || x == typeof(IList<>))); 
    } 

    private static object GetArrayOrGenericListInstance(Type arrayOrIListType, string separatedValues, string separator) 
    { 
     if (separatedValues == null) 
      return null; 

     if (separator == null) 
      throw new ArgumentNullException("separator"); 

     if (arrayOrIListType.IsArray) 
     { 
      Type arrayElementType = arrayOrIListType.GetElementType(); 
      ArrayList valueList = GetValueList(separatedValues, separator, arrayElementType); 

      return valueList.ToArray(arrayElementType); 
     } 

     Type listElementType = GetListElementType(arrayOrIListType); 

     if (listElementType != null) 
      return GetGenericIListInstance(arrayOrIListType, GetValueList(separatedValues, separator, listElementType)); 

     throw new InvalidOperationException("The type could not be handled, this should never happen: " + arrayOrIListType); 
    } 

    private static Type GetListElementType(Type genericListType) 
    { 
     Type listElementType = null; 

     foreach (Type type in genericListType.GetInterfaces()) 
     { 
      if (type.IsGenericType && type == typeof(IList<>).MakeGenericType(type.GetGenericArguments()[0])) 
      { 
       listElementType = type.GetGenericArguments()[0]; 
       break; 
      } 
     } 

     return listElementType; 
    } 

    private static object GetGenericIListInstance(Type arrayOrIListType, ArrayList valueList) 
    { 
     object result = Activator.CreateInstance(arrayOrIListType); 
     const BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public; 

     foreach (object value in valueList) 
     { 
      arrayOrIListType.InvokeMember("Add", flags, null, result, new[] { value }); 
     } 

     return result; 
    } 

    private static ArrayList GetValueList(string separatedValues, string separator, Type memberType) 
    { 
     string[] values = separatedValues.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries); 

     ArrayList valueList = new ArrayList(); 

     foreach (string value in values) 
     { 
      valueList.Add(Convert.ChangeType(value, memberType)); 
     } 

     return valueList; 
    } 

    #endregion 
} 

}

Các vấn đề liên quan