Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a controller which looks like;

[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 is;

@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 this code, The ModeState.IsValid property becomes false (I saw through debugging). However, when I remove ModeState.IsValid, the insertation is done successfully and everything works exactly what I want.
I need ModeState.IsValid property for validating my view.
Updated: My viewmodel is;

[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 the error. the problem is

{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)}
like image 578
Idrees Khan Avatar asked Dec 05 '22 14:12

Idrees Khan


1 Answers

When in debug, check the ModelState for errors. It's a key/value dictionary with all the properties required to make the model valid. If you check the Values-property you can find the value with the Errors-list that is not empty and see what the error is.

Example of ModelState errors

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

var errors = ModelState.Where(v => v.Value.Errors.Any());
like image 105
Mario S Avatar answered Dec 07 '22 02:12

Mario S