Why doesn't My ModelState.IsValid return true in Asp.Net MVC4?

I have a controller that looks like this:

[HttpPost] [Authorize(Roles = "Admin")] public ActionResult ProjectAdd(PortfolioViewModel model, int[] categories, HttpPostedFileBase thumbnail, HttpPostedFileBase image) { model.ProjectImage = System.IO.Path.GetFileName(image.FileName); model.ProjectThubmnail = System.IO.Path.GetFileName(thumbnail.FileName); using (PortfolioManager pm = new PortfolioManager()) { using (CategoryManager cm = new CategoryManager()) { if (ModelState.IsValid) { bool status = pm.AddNewProject(model, categories); } ViewBag.Categories = cm.GetAllCategories(); ViewBag.ProjectsList = pm.GetAllProjects(); } } return View(model); } 

My view:

 @using (Html.BeginForm("projectAdd", "home", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.ValidationSummary(true) <fieldset> <legend>Add New Project</legend> <div class="editor-label"> @Html.LabelFor(model => model.ProjectHeading) </div> <div class="editor-field"> @Html.EditorFor(model => model.ProjectHeading) @Html.ValidationMessageFor(model => model.ProjectHeading) </div> <div class="editor-label"> @Html.LabelFor(model => model.ProjecctUrl) </div> <div class="editor-field"> @Html.EditorFor(model => model.ProjecctUrl) @Html.ValidationMessageFor(model => model.ProjecctUrl) </div> <div class="editor-label"> @Html.LabelFor(model => model.ProjectLongDescription) </div> <div class="editor-field"> @Html.EditorFor(model => model.ProjectLongDescription) @Html.ValidationMessageFor(model => model.ProjectLongDescription) </div> <div class="editor-label"> @Html.LabelFor(model => model.PromoFront) </div> @Html.EditorFor(model => model.PromoFront) @Html.ValidationMessageFor(model => model.PromoFront) <div class="editor-label"> <label for="thumbnail">Thumbnail</label> </div> <div class="editor-field"> <input type="file" name="thumbnail" id="thumbnail" /> </div> <div class="editor-label"> <label for="image">Image</label> </div> <div class="editor-field"> <input type="file" name="image" id="image" /> </div> <div class="editor-label"> <label for="categories">Categories</label> </div> @foreach (var c in categories) { <input type="checkbox" name="categories" value="@c.CategoryId"> @c.CategoryName } <p> <input type="submit" value="Create" class="submit" /> </p> </fieldset> } 

When I try to use this code, the ModeState.IsValid property becomes false (I saw through debugging). However, when I delete ModeState.IsValid , the insert is successful and everything works exactly the way I want.
I need the ModeState.IsValid property to validate my view.

Updated: My view model:

 [Key] public int ProjectId { get; set; } [Required(ErrorMessage="Please enter project heading")] public string ProjectHeading { get; set; } [Required(ErrorMessage = "Please enter project Url")] public string ProjecctUrl { get; set; } [Required(ErrorMessage = "Please enter project description")] public string ProjectLongDescription { get; set; } public string ProjectShortDescription { get { var text = ProjectLongDescription; if (text.Length > ApplicationConfiguration.ProjectShortDescriptionLength) { text = text.Remove(ApplicationConfiguration.ProjectShortDescriptionLength); text += "..."; } return text; } } public bool PromoFront { get; set; } [Required(ErrorMessage = "You must sepcify a thumbnail")] public string ProjectThubmnail { get; set; } [Required(ErrorMessage = "You must select an image")] public string ProjectImage { get; set; } public int CategoryId { get; set; } public IEnumerable<Category> Categories { get; set; } 

Updated 2: I found an error. problem

 {System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'PortfolioMVC4.Models.Category' failed because no type converter can convert between these types. at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType) at System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType) at System.Web.Mvc.ValueProviderResult.ConvertTo(Type type, CultureInfo culture) at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState, String modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)} 
+4
source share
2 answers

When debugging, check for ModelState errors. This is a key / value dictionary with all the properties necessary for a model to be valid. If you check Values -property, you can find the value with Errors -list which is not empty and see what the error is.

Example of ModelState errors

Or add this line of code to the action method to get all errors for the model:

 var errors = ModelState.Where(v => v.Value.Errors.Any()); 
+12
source

You need to rename your categories action parameter to another, because your PortfolioViewModel model already has a property with the name categories , which has a completely different type and which disrupts the model change:

 [HttpPost] [Authorize(Roles = "Admin")] public ActionResult ProjectAdd( PortfolioViewModel model, int[] categoryIds, HttpPostedFileBase thumbnail, HttpPostedFileBase image ) { ... } 

Now, obviously, you will also have to update your view to match the flag name.

Although this may solve your problem, I highly recommend that you use view models and stop transferring your domain models to views.

+4
source

Source: https://habr.com/ru/post/1437053/


All Articles