如何将整数列表传递给MVC操作?

时间:2010-08-10 15:54:19

标签: c# asp.net-mvc

我可以使用List吗?

7 个答案:

答案 0 :(得分:8)

您需要通过将每个整数添加到POST或GET查询字符串来将它们传递给您的操作:

myints=1&myints=4&myints=6

然后在您的操作中,您将执行以下操作

public ActionResult Blah(List<int> myints)
然后,MVC将使用1,4和6

填充列表

有一点需要注意。您的查询字符串中不能包含括号。有时,当形成javascript列表时,您的查询字符串将如下所示:

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

这将导致您的List为空(或计数为零)。 MVC无法正确绑定模型。

答案 1 :(得分:7)

Scott Hanselman有一个很好的教程,可以做到这一点here.

答案 2 :(得分:1)

选择正确的系列。具体取决于哪个版本:

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

答案 3 :(得分:1)

如果您尝试从某个界面项(例如表)发送列表,则只需在HTML中将其名称属性设置为:CollectionName [Index] 例如:

<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) {
}

IntList参数将按顺序接收包含1和2的列表

答案 4 :(得分:0)

用法:

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

}

这里是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
}

}

答案 5 :(得分:0)

如果此线程中的其他所有帖子均未起作用,并且您不想花费大量时间来学习MVC参数传递的特质,那么这里是一个非常好的解决方法。在JavaScript中,对列表进行字符串化:

var jSelected = JSON.stringify(selectedIDs);

然后在控制器中反序列化它们:

List<int> iCodes = new List<int>();
int iCode = 0;
string[] sNums = IDs.Trim('[').Trim(']').Split(',');

foreach (string sCode in sNums)
{
    if (int.TryParse(sCode, out iCode))
        iCodes.Add(iCode);
}

答案 6 :(得分:-2)

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

 }