具有键“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>'
问题描述
我有以下视图模型
public class ProjectVM
{
....
[Display(Name = "Category")]
[Required(ErrorMessage = "Please select a category")]
public int CategoryID { get; set; }
public IEnumerable<SelectListItem> CategoryList { get; set; }
....
}
和以下控制器方法来创建一个新项目并分配一个Category
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:具有键CategoryID"的 ViewData 项的类型为System.Int32",但必须为IEnumerable
InvalidOperationException: The ViewData item that has the key 'CategoryID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
使用 @Html.DropDownList()
方法时会发生同样的错误,如果我使用 ViewBag
或 ViewData
传递 SelectList.
The same error occurs using the @Html.DropDownList()
method, and if I pass the SelectList using a ViewBag
or ViewData
.
推荐答案
该错误意味着 CategoryList
的值为 null(因此 DropDownListFor()
方法期望第一个参数的类型为 IEnumerable
).
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>
).
您没有为 CategoryList
中每个 SelectListItem
的每个属性生成输入(您也不应该),因此 SelectList
没有值被发布到控制器方法中,因此POST方法中model.CategoryList
的值为null
.如果返回视图,则必须首先重新分配 CategoryList
的值,就像在 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
}
解释内部工作原理(源代码可以在看到这里)
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)
检查selectList
(@Html.DropDownListFor()
的第二个参数)是否为null
which checks if the selectList
(the second parameter of @Html.DropDownListFor()
) is null
// 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()
的第一个参数(在本例中为 CategoryID
)
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>"));
}
因为属性 CategoryID
是 int
的类型,所以它不能被强制转换为 IEnumerable
并抛出异常(定义在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<SelectListItem>"类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!