Сводка проверки на стороне клиента MVC не отображается, если модель недействительна

Я использую пакет nuget MVC Validation под названием MVC Foolproof Validation.

Я использую его в своей модели, чтобы установить для параметра required значение true, если другое свойство модели было пустым. Часть проверки работает, так как ModelState правильно устанавливается как недопустимое, когда поля Id и Location остаются пустыми. Проверяя ошибки в массиве ModelState, я вижу, как он работает.

Моя проблема в том, что сводка проверки на стороне клиента не отображается. Вот как я все настроил. Может ли кто-нибудь обнаружить мою проблему?

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

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

На мой взгляд, я настраиваю сводку проверки и входные данные следующим образом.

<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>

В моем действии контроллера я проверяю состояние модели. Нужно ли вызывать ModelState.AddModelError(..). Я пробовал это, но, возможно, мне нужно это назвать.

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

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

person user48408    schedule 14.08.2017    source источник
comment
@Html.ValidationSummary(true, ..) означает, что он исключает ошибки на уровне ресурса. Но у вас уже есть @Html.ValidationMessageFor(model => model.SearchCriteria.LocationId, ...), который будет отображать сообщение об ошибке в этом месте, если Id равно null и вы не укажете значение для LocationId. И если вы настроили это правильно, будет отображаться сообщение об ошибке, и вы даже не сможете отправить форму, если она недействительна, поэтому тот факт, что вы нажмете метод контроллера, предполагает другие проблемы.   -  person    schedule 15.08.2017
comment
И тот факт, что параметр в методе SearchCriteria, когда модель в вашем представлении не выглядит @model SearchCriteria, предполагает еще больше проблем.   -  person    schedule 15.08.2017


Ответы (3)


Измените логический параметр (excludePropertyErrors) во вспомогательной строке ValidationSummary на false:

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

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

person Philipp Grathwohl    schedule 14.08.2017
comment
Это не имело никакого значения. Я должен заявить, что, как и сводка проверки, не отображается, так и сообщение об ошибке проверки под самим элементом управления не отображается... - person user48408; 14.08.2017
comment
Это может иметь какое-то отношение к непоследовательному использованию вашего класса модели представления. Вы используете model.SearchCriteria.LocationId в своем представлении, и ваш контроллер получает параметр SearchCriteria. Это кажется странным. Можете ли вы попробовать использовать только SearchCriteria в своем представлении и контроллере? - person Philipp Grathwohl; 14.08.2017
comment
Я не понимаю. Кажется стандартным, представление имеет модель с некоторыми свойствами, и каждое из этих свойств имеет свои собственные критерии проверки, указанные в аннотациях данных. Я должен упустить то, что вы говорите? - person user48408; 14.08.2017
comment
Я только что попробовал пример проекта с описанным вами случаем, и он работал нормально. Но вы не опубликовали все свои классы и просмотр ... может быть, есть еще одна проблема, которую мы не видим ... - person Philipp Grathwohl; 15.08.2017
comment
Привет Филипп, спасибо за обновление. Да, вы правы, поведение по умолчанию будет работать, но я делал свой запрос в запросе ajax и предотвращал обратную передачу (неудивительно!). я собираюсь обновить - person user48408; 15.08.2017

В моем случае я решил изменить его с «ModelOnly» на «All»:

От:

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

To:

<div asp-validation-summary="All" class="text-danger"></div>
person Fellipe Borges    schedule 14.01.2020
comment
ValidationSummary.All отображает проверки как на уровне свойств, так и на уровне модели. ValidationSummary.ModelOnly отображает только сообщения проверки, которые относятся к уровню модели. Источник - person Fellipe Borges; 12.09.2020

Моя проблема заключалась в том, что мой призыв к моему действию выполнялся через ajax. Я действительно должен был указать, люди, которые помогли здесь, сразу бы диагностировали проблему. Когда состояние модели было недействительным, я возвращал новый вид (searchViewModel), но мне пришлось обновить его, чтобы вернуть ошибки в 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 });
    }
person user48408    schedule 15.08.2017