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; }
}
}
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);
}
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);
}
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?
model.CategoriesList
in the post action also. Then you can see the validation errors. The error you are getting occurs whenmodel.CategoriesList
is null and in that case framework tries to read the list fromViewData
and that value is not expected type as specified in that error message. – Mat Jmodel.CategoriesList
isnull
so you get that error. If you return the view, you must reassign theSelectList
– user3559349return View(model);
, just copy the code you have in the GET method for assigningmodel.CategoriesList
i.e.var categories = ....; model.CategoriesList = .....;
– user3559349