这有钥匙'XXX'的ViewData的产品类型“System.Int32”,但必须是类型为“IEnumerable的< SelectListItem>' [英] The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'

查看:991
本文介绍了这有钥匙'XXX'的ViewData的产品类型“System.Int32”,但必须是类型为“IEnumerable的< SelectListItem>'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下视图模型

public class ProjectVM
{
    ....
    [Display(Name = "Category")]
    [Required(ErrorMessage = "Please select a category")]
    public int CategoryID { get; set; }
    public IEnumerable<SelectListItem> CategoryList { get; set; }
    ....
}

和下面的控制器方法来创建一个新的项目,并指定一个类别

and the following controller method to create a new Project and assign a Category

public ActionResult Create()
{
    ProjectVM model = new ProjectVM
    {
        CategoryList = new SelectList(db.Categories, "ID", "Name")
    }
    return View(model);
}

public ActionResult Create(ProjectVM model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
    // Save and redirect
}

和视图

@model ProjectVM
....
@using (Html.BeginForm())
{
    ....
    @Html.LabelFor(m => m.CategoryID)
    @Html.DropDownListFor(m => m.CategoryID, Model.CategoryList, "-Please select-")
    @Html.ValidationMessageFor(m => m.CategoryID)
    ....
    <input type="submit" value="Create" />
}

该视图显示正确,但在提交表单的时候,我得到了以下错误消息

The view displays correctly but when submitting the form, I get the following error message

出现InvalidOperationException:具有关键的类别ID的类型为System.Int32,但必须是类型的ViewData的项目'的IEnumerable&LT; SelectListItem&GT;

InvalidOperationException: The ViewData item that has the key 'CategoryID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.

时使用 @ Html.DropDownList()方法同样的错误,如果我通过使用一个的SelectList ViewBag 的ViewData

The same error occurs using the @Html.DropDownList() method, and if I pass the SelectList using a ViewBag or ViewData.

推荐答案

错误意味着所属分类值为null(并因此在 DropDownListFor()方法要求第一个参数是类型的的IEnumerable&LT; SelectListItem方式&gt;

The error means that the value of CategoryList is null (and as a result the DropDownListFor() method expects that the first parameter is of type IEnumerable<SelectListItem>).

您没有在所属分类生成每个 SelectListItem 的每个属性的输入(和也不应该知道),所以为的SelectList 张贴到控制器的方法,并没有因此值 model.CategoryList 中的POST方法的价值为。如果返回的视图,您必须首先重新分配的值所属分类,就像你在GET方法一样。

You are not generating an input for each property of each SelectListItem in CategoryList (and nor should you) so no values for the SelectList are posted to the controller method, and therefore the value of model.CategoryList in the POST method is null. If you return the view, you must first reassign the value of CategoryList, just as you did in the GET method.

public ActionResult Create(ProjectVM model)
{
    if (!ModelState.IsValid)
    {
        model.CategoryList = new SelectList(db.Categories, "ID", "Name"); // add this
        return View(model);
    }
    // Save and redirect
}

要解释的内部运作(来源$ C ​​$ C能<一个href=\"https://aspnetwebstack.$c$cplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs\">seen这里)

To explain the inner workings (the source code can be seen here)

中的每一个超负荷的DropDownList() DropDownListFor()最终调用下面的方法

Each overload of DropDownList() and DropDownListFor() eventually calls the following method

private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
  string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
  IDictionary<string, object> htmlAttributes)

它检查是否选择列表(第二个参数 @ Html.DropDownListFor())的

// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
    selectList = htmlHelper.GetSelectData(name);
    usedViewData = true;
}

这反过来又来电

private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)

其计算的 @ Html.DropDownListFor()(在这种情况下,类别id

which evaluates the the first parameter of @Html.DropDownListFor() (in this case CategoryID)

....
o = htmlHelper.ViewData.Eval(name);
....
IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
if (selectList == null)
{
    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
        MvcResources.HtmlHelper_WrongSelectDataType,
        name, o.GetType().FullName, "IEnumerable<SelectListItem>"));
}

由于财产类别id 是typ​​eof运算 INT ,它不能被转换为的IEnumerable&LT; SelectListItem&GT ; 和异常被抛出(在定义的 MvcResources.resx 文件作为)

Because property CategoryID is typeof int, it cannot be cast to IEnumerable<SelectListItem> and the exception is thrown (which is defined in the MvcResources.resx file as)

<data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
    <value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
</data>

这篇关于这有钥匙'XXX'的ViewData的产品类型“System.Int32”,但必须是类型为“IEnumerable的&LT; SelectListItem&GT;'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆