3
votes

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);
    }
3
@Html.ValidationSummary(true, ..) means it excludes property level errors. But you already have @Html.ValidationMessageFor(model => model.SearchCriteria.LocationId, ...) which will display the error mesage at that location if Id is null and you do not provide a value for LocationId. And if you have set this up correctly, the error message will be dsplayed and you form will not even be able to be submitted if its invalid so the fact you hitting the controller method suggest other problems - user3559349
And the fact that the parameter in the method is SearchCriteria when the model in your view does not appear to be @model SearchCriteria suggest even more problems - user3559349

3 Answers

3
votes

Change the boolean parameter (excludePropertyErrors) in the ValidationSummary helper line to false:

@Html.ValidationSummary(false, "", new {@class = "text-danger"})

See https://msdn.microsoft.com/de-de/library/ee839464(v=vs.118).aspx

1
votes

In my case I solved it changing from 'ModelOnly' to 'All':

From:

<div asp-validation-summary="ModelOnly" class="text-danger"></div>

To:

<div asp-validation-summary="All" class="text-danger"></div>
0
votes

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 });
    }