C# 具有键';类别ID';类型为';System.Int32';但必须为'型;IEnumerable<;选择列表项>';
我试图将一些新帖子保存到我的数据库中,但我多次出错。。我在下面有一个“Posts.cs”类 在我的视图CreatePost.cshtml中,我有C# 具有键';类别ID';类型为';System.Int32';但必须为'型;IEnumerable<;选择列表项>';,c#,asp.net,asp.net-mvc-4,C#,Asp.net,Asp.net Mvc 4,我试图将一些新帖子保存到我的数据库中,但我多次出错。。我在下面有一个“Posts.cs”类 在我的视图CreatePost.cshtml中,我有 @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <hr /> @Html.ValidationSummary(true, "", new { @class =
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.PostTitle, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PostTitle, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PostTitle, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PostContent, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@*@Html.TextAreaFor(model => model.PostContent, new { htmlAttributes = new { @class = "form-control" } })*@
<textarea class="form-control" name="PostContent" id="PostContent" rows="3"></textarea>
@Html.ValidationMessageFor(model => model.PostContent, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CategoryId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.CategoryId, Model.CategoriesList, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
我可以看到ModelState.IsValid返回false,我得到的错误是
The ViewData item that has the key 'CategoryId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
具有键“CategoryId”的ViewData项的类型为“System.Int32”,但必须为“IEnumerable”类型。
请如何解决此问题?ModelState总是返回false的原因是属性
CategoryName
具有[Required]
属性,并且您不呈现控件并回发值,因此它总是null
,因此无效。但是,CategoryName
与下拉列表关联的选定类别相关,因此您应该删除此属性,只需依赖绑定到下拉列表的CategoryId
该错误的原因是,当您返回视图时(由于上述问题,该视图总是发生),您没有重新分配CategoriesList
的值,因此它的null
和@Html.DropDownListFor(model=>model.CategoryId,model.CategoriesList,…)
抛出异常
为了避免重复,您可以将公共代码重新分解为私有方法(注意,这假设您将公共列表分类列表{get;set;}
更改为公共选择列表分类列表{get;set;}
)
现在可以在GET方法和POST方法中调用它
[HttpGet]
public ActionResult CreatePost()
{
AddPostsVM model = new AddPostsVM();
ConfigureEditModel(model);
return View(model);
}
[HttpPost]
public ActionResult CreatePost(AddPostsVM model)
{
if (!ModelState.IsValid)
{
ConfigureEditModel(model); // repopulate select list
return View(model); // return the view to correct errors
}
// Save and redirect
}
在post操作中初始化
模型.CategoriesList
。然后您可以看到验证错误。当model.CategoriesList
为空时,您会遇到错误,在这种情况下,framework会尝试从ViewData
读取列表,而该值不是错误消息中指定的预期类型。@Matthew我这样做了,但我没有得到任何错误,除了我自己设置的on之外,如果modelstat无效,我应该得到“无效模型”“除此之外,没有error@ibnhamza,当您返回视图时,model.CategoriesList
为null
,因此您会得到该错误。如果返回视图,则必须重新分配选择列表
@StephenMuecke。您能帮我用正确的代码重写代码吗。我会很感激的。从@ibnhamza开始,在POST方法中,返回视图(model)行之前,一直在涉猎
,只需复制GET方法中用于分配model.CategoriesList
的代码,即var categories=。。。。;model.CategoriesList=代码>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.PostTitle, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PostTitle, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PostTitle, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PostContent, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@*@Html.TextAreaFor(model => model.PostContent, new { htmlAttributes = new { @class = "form-control" } })*@
<textarea class="form-control" name="PostContent" id="PostContent" rows="3"></textarea>
@Html.ValidationMessageFor(model => model.PostContent, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CategoryId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.CategoryId, Model.CategoriesList, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
[HttpPost]
public ActionResult CreatePost(AddPostsVM model)
{
try
{
if (ModelState.IsValid)
{
var newPost = db.Posts.Create();
newPost.PostTitle = model.PostTitle;
newPost.PostContent = model.PostContent;
FormsIdentity identity = (FormsIdentity)User.Identity;
int nUserID = Int32.Parse(identity.Ticket.UserData);
newPost.AuthorId = nUserID;
newPost.CategoryId = model.CategoryId;
newPost.DateCreated = DateTime.Now;
db.Posts.Add(newPost);
db.SaveChanges();
return RedirectToAction("Index", "Posts");
}
else
{
ModelState.AddModelError("", "Invalid Model");
}
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Debug.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Debug.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
return View(model);
}
The ViewData item that has the key 'CategoryId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
private void ConfigureEditModel(AddPostsVM model)
{
model.CategoriesList = new SelectList(db.Categories, "CategoryID", "CategoryName");
// any other common stuff
}
[HttpGet]
public ActionResult CreatePost()
{
AddPostsVM model = new AddPostsVM();
ConfigureEditModel(model);
return View(model);
}
[HttpPost]
public ActionResult CreatePost(AddPostsVM model)
{
if (!ModelState.IsValid)
{
ConfigureEditModel(model); // repopulate select list
return View(model); // return the view to correct errors
}
// Save and redirect
}