具有关键的“类别ID”的ViewData的产品类型“System.Int32”,但必须是类型为“IEnumerable的&LT; SelectListItem&GT;' [英] The ViewData item that has the key 'CategoryId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'
问题描述
我是想节省一些新职位,我的数据库,但我得到一个错误多次..我有以下
I was trying to save some new posts to my database but i got an error repeatedly.. I have a class "Posts.cs" below
public partial class Post
{
public Post()
{
this.Replies = new HashSet<Reply>();
}
public int PostId { get; set; }
public string PostTitle { get; set; }
public string PostContent { get; set; }
public int AuthorId { get; set; }
public int CategoryId { get; set; }
public System.DateTime DateCreated { get; set; }
public virtual Category Category { get; set; }
public virtual UserProfile UserProfile { get; set; }
public virtual ICollection<Reply> Replies { get; set; }
}
}
和一个ViewModel这是我用来渲染视图为用户添加的帖子
and a ViewModel which i used to render a view for users to add posts
public class AddPostsVM
{
[Display(Name = "CategoryId")]
public int CategoryId { get; set; }
[Required()]
[Display(Name="Title")]
public string PostTitle { get; set; }
[Required()]
[Display(Name="Content")]
public string PostContent { get; set; }
[Required()]
[Display(Name="Select a Category")]
public string CategoryName { get; set; }
public List<SelectListItem>CategoriesList { get; set; }
}
我使用的视图模型渲染视图中的下拉列表中,以便获取类别列表中的数据库,这样当用户添加后,他们可以选择他们想要的职位属于该类别
I used the view model to render a view with a dropdown list in the view to fetch the list of categories in the database so that when users are adding a post they can select the category they want the post to belong to
[HttpGet]
public ActionResult CreatePost()
{
AddPostsVM model = new AddPostsVM();
var categories = (from c in db.Categories
select new
{
CategoryName = c.CategoryName,
CategoryId = c.CategoryId
}).ToList();
model.CategoriesList = categories.Select(c => new SelectListItem
{
Text = c.CategoryName,
Value = c.CategoryId.ToString()
}).ToList();
return View(model);
}
在我看来CreatePost.cshtml我有这个
In my view CreatePost.cshtml I have this
@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>
}
每当我尝试使用以下
Whenever i try to add a new post to the database by using the Post action below
[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);
}
我可以看到ModelState.IsValid是返回false,我得到的错误说
I could see that the ModelState.IsValid was returning false and I got the error saying
The ViewData item that has the key 'CategoryId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
请我该如何解决这个问题?
Please how do i solve this?
推荐答案
之所以的ModelState
总是返回false就是财产类别名称
有 [必需]
属性,你不渲染控制和后回值,因此它总是空
,因此无效。然而类别名称
有关,与你的下拉列表相关联,所以你应该删除这个属性,只是依靠的CategoryId
这势必将DropDownList。
The reason that ModelState
always returns false is that property CategoryName
has the [Required]
attribute and you do not render a control and post back a value so its always null
and therefore invalid. However CategoryName
is related to the selected Category associated with you dropdown list so you should remove this property and just rely on the CategoryId
which is bound to the dropdownlist.
的原因的错误是,当你返回视图(它总是发生监守上面的问题),你是不是重新分配 CategoriesList
的值,因此其空
和 @ Html.DropDownListFor(型号=&GT; model.CategoryId,Model.CategoriesList,..)
投例外。
The reason for the error is that when you return the view (which was always happening becuase of the issue above), you are not reassigning the value of CategoriesList
so its null
and @Html.DropDownListFor(model => model.CategoryId, Model.CategoriesList, ..)
throws the exception.
要避免重复,你可以重新因素共同code变成一个私有方法(注意:这里假设你改变公开名单&LT; SelectListItem&GT; CategoriesList {获取;集;}
到公开的SelectList CategoriesList {获取;设置;}
)
To avoid repetition , you can re-factor common code into a private method (note this assumes you change public List<SelectListItem> CategoriesList { get; set; }
to public SelectList CategoriesList { get; set; }
)
private void ConfigureEditModel(AddPostsVM model)
{
model.CategoriesList = new SelectList(db.Categories, "CategoryID", "CategoryName");
// any other common stuff
}
您现在可以调用GET方法和POST方法
which you can now call in the GET method and the POST method
[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
}
这篇关于具有关键的“类别ID”的ViewData的产品类型“System.Int32”,但必须是类型为“IEnumerable的&LT; SelectListItem&GT;'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!