该错误意味着该值CategoryList
为空(因此DropDownListFor()
方法期望第一个参数的类型IEnumerable<SelectListItem>
).
您不会为每个属性的每个属性生成输入SelectListItem
in CategoryList
(你也不应该)所以没有值SelectList
被发布到控制器方法,因此值model.CategoryList
在 POST 方法中是null
。如果返回视图,必须先重新赋值CategoryList
,就像您在 GET 方法中所做的那样。
public ActionResult Create(ProjectVM model)
{
if (!ModelState.IsValid)
{
model.CategoryList = new SelectList(db.Categories, "ID", "Name"); // add this
return View(model);
}
// Save and redirect
}
解释内部工作原理(源代码可以是在这里看到)
每次超载DropDownList()
and DropDownListFor()
最终调用以下方法
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()
) 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
)
....
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<SelectListItem>
并抛出异常(在MvcResources.resx
文件为)
<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>