本文介绍了具有关键的“类别ID”的ViewData的产品类型“System.Int32”,但必须是类型为“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;'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 18:24