具有键“XXX”的ViewData项的types为“System.Int32”,但必须为“IEnumerable <SelectListItem>”types
我有以下视图模型
public class ProjectVM { .... [Display(Name = "Category")] [Required(ErrorMessage = "Please select a category")] public int CategoryID { get; set; } public IEnumerable<SelectListItem> CategoryList { get; set; } .... }
和下面的控制器方法来创build一个新的项目并分配一个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" /> }
该视图正确显示但提交表单时,我收到以下错误信息
InvalidOperationException:具有“CategoryID”键的ViewData项的types为“System.Int32”,但必须是“IEnumerable <SelectListItem>”types。
使用@Html.DropDownList()
方法发生同样的错误,如果我使用ViewBag
或ViewData
传递SelectList。
该错误意味着CategoryList
值为null(因此DropDownListFor()
方法期望第一个参数的types为IEnumerable<SelectListItem>
)。
您不会为CategoryList
的每个SelectListItem
每个属性生成input(也不应该),因此SelectList
值不会发布到控制器方法,因此POST方法中的model.CategoryList
的值为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()
和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()
)的第二个参数是否为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
是typeof int
,因此无法将其转换为IEnumerable<SelectListItem>
并抛出exception(在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>
- MVC Html.BeginForm使用区域
- 没有布局的剃刀视图
- 未find方法:'!! 0 System.Array.Empty()'。 ASApp.BundleConfig.RegisterBundles(BundleCollection包)inBundleConfig.cs
- 如何在ASP.NET MVC中查找动作的绝对URL?
- 如何在Razor中声明局部variables?
- 新的HTML5inputtypes的ASP.NET MVC HTML帮助器方法
- 具有多个路由值的ASP.NET MVC URL路由
- 如何在asp.net mvc中将date时间值作为URIparameter passing?
- Asp.Net MVC中的DataAnnotations StringLength的文本框的maxlength属性