Search code examples
c#asp.net-mvcasp.net-mvc-validationfoolproof-validation

MVC Client Side Validation Summary not showing when Model is Invalid


I'm using the MVC Validation nuget package called MVC Foolproof Validation.

I'm using it on my model to set a required to true if another model property was empty. The validation part works, as the ModelState is correctly set to invalid when the Id field and Location field are left empty. Inspecting the errors on the ModelState array I can see its working.

My problem is that the client side validation summary does not display. Here is how I've set things up. Can anyone spot my problem?

    [DisplayName("Image Id")]
    public string Id{ get; set; }

    [DisplayName("Location Id")]
    [RequiredIfEmpty("Id", ErrorMessage = "You must..etc"]
    public string LocationId{ get; set; }

In my view I'm setting up the validation summary and inputs as follows

<div class="form-horizontal">
    <hr/>
    @Html.ValidationSummary(true, "", new {@class = "text-danger"})

    <div class="form-group">
        @Html.LabelFor(model => model.SearchCriteria.Id, htmlAttributes: new {@class = "control-label col-md-2"})
        <div class="col-md-10">
            @Html.EditorFor(model => model.SearchCriteria.Id, new {htmlAttributes = new {@class = "form-control"}})
            @Html.ValidationMessageFor(model => model.SearchCriteria.Id, "", new {@class = "text-danger"})
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.SearchCriteria.LocationId, htmlAttributes: new {@class = "control-label col-md-2"})
        <div class="col-md-10">
            @Html.EditorFor(model => model.SearchCriteria.LocationId, new {htmlAttributes = new {@class = "form-control"}})
            @Html.ValidationMessageFor(model => model.SearchCriteria.LocationId,"", new {@class = "text-danger"})
        </div>
    </div>

In my controller action I'm checking the Model state. Do I need to call ModelState.AddModelError(..). I've tried that but perhaps there is a way I need to call it.

    [HttpPost]
    public ActionResult Search(SearchCriteria searchCriteria)
    {
        var searchViewModel = new SearchViewModel
        {
            SearchCriteria = searchCriteria
        };

        if (ModelState.IsValid)
        {
            ...
        }
        //ModelState.AddModelError("LocationId", "test");
        return View(searchViewModel);
    }

Solution

  • My problem was that my call to my action was being done through ajax. I really should have specified, people who helped here would have diagnosed the problem immediately. When the modelstate was invalid i was returning a new View(searchViewModel) but I had to update that to return the errors in json.

        [HttpPost]
        public ActionResult Search(SearchCriteria searchCriteria)
        {
            if (ModelState.IsValid)
            {
                var searchResults = _searchProvider.GetData(searchCriteria);
    
                return Json(new
                {
                    searchResults
                }, JsonRequestBehavior.AllowGet);
            }
    
            string errorMessages = string.Join(" <br /> ", this.ModelState.Values
                .SelectMany(v => v.Errors)
                .Select(e => e.ErrorMessage));
    
            return this.Json(new { HasError = true, ErrorMessages = errorMessages });
        }