Как отобразить конкретные ошибки ModelState в ASP.NET Core MVC? - PullRequest
1 голос
/ 05 июня 2019

В одном из моих действий контроллера первое, что я делаю, - это передаю модель новому действию, которое, по сути, просто анализирует входные данные, чтобы определить, ввел ли пользователь правильную дату. Затем возвращается модель и проверяется ModelState.IsValid.

public Import ValidateUploadModel(Import Model)
    {
        // DO not allow future dates
        if (Model.CurrMoInfo.CurrMo > DateTime.Now)
        {
            ModelState.AddModelError("FutureDate", "You cannot assign a future date.");
        }
        //Do not allow dates from the same month (we run the processing a month behind)
        if (Model.CurrMoInfo.CurrMo.Month == DateTime.Now.Month)
        {
            ModelState.AddModelError("SameMonth", "You must process a previous month.");
        }

        //Ensure day is last day of a previous month
        if (Model.CurrMoInfo.CurrMo.Day != DateTime.DaysInMonth(Model.CurrMoInfo.CurrMo.Year, Model.CurrMoInfo.CurrMo.Month))
        {
            ModelState.AddModelError("LastDay", "You must enter the last day of the month.");
        }

        //Do not allow dates older than 12 months back
        if (Model.CurrMoInfo.CurrMo < DateTime.Now.AddMonths(-12))
        {
            ModelState.AddModelError("TooOld", "Date must not be older than a year.");
        }

        return Model;
    }

В тот момент, когда я знаю, что у меня есть ошибки состояния модели, я могу корректно показать их в моем виде бритвы, поставив следующее

<span class="text-danger">@Html.ValidationSummary(false)</span>

Итак, поскольку все мои ошибки состояния модели относятся к одному и тому же вводу на странице, я могу смело делать это Но что, если у меня есть различные входы с различными ошибками, которые мне нужно отображать независимо друг от друга? Как бы я поступил так? Кроме того, есть ли лучший (или более подходящий) способ сделать это помимо использования @ Html.ValidationSummary?

Я просмотрел документы Microsoft и несколько десятков вопросов StackOverflow, чтобы попытаться перевести более старые ответы в .Net Core, чтобы делать дела без удачи.

Изменить для ясности:

Вот вся карта в виде бритвы:

<div class="card-body">

                @if (Model.StagingCount == 0)
                {
                    <input asp-for="@Model.CurrMoInfo.CurrMo" type="date" required class="col-lg-12" />
                }
                else
                {
                    <input asp-for="@Model.CurrMoInfo.CurrMo" type="date" disabled="disabled" required class="col-lg-12" />
                }

                <span class="text-danger">@Html.ValidationSummary(false)</span>

            </div>

Входные данные для свойства модели, однако они не аннотированы. Я написал свои собственные правила и вручную добавляю ошибки в состояние модели, если правила не соблюдаются. У меня работает код, однако он не масштабируется, когда мне нужно проверить больше полей. Я просто хочу знать, как лучше это сделать.

1 Ответ

1 голос
/ 05 июня 2019

В приведенном выше примере вы не следуете стандартной практике.

Для простых проверок, подобных этой (когда вы проверяете значение только в одном поле), ключ, который вы используете для размещения сообщения об ошибке в ModelState, должен совпадать с именем затронутого поля в модели. , В вашем случае на самом деле все ваши ошибки должны быть зарегистрированы с ключом CurrMoInfo.CurrMo. Только само сообщение об ошибке должно отличаться. Насколько я могу судить, использование собственного ключа для каждой конкретной ошибки не добавляет никакой ценности вашему приложению. Вы не используете это так, как это было задумано.

Если вы регистрируете их все по CurrMoInfo.CurrMo, то вы можете использовать помощник по тегам asp-validation-for, чтобы создать поле, отображающее ошибки, относящиеся именно к этому полю, например,

<span asp-validation-for="CurrMoInfo.CurrMo" class="text-danger"></span>

Затем вы можете (необязательно) использовать ValidationSummary для (как следует из заголовка) суммировать все ошибки для всей модели - и для отображения любых дополнительных ошибок модели, которые вы, возможно, создали, которые не относятся к одному конкретному полю.

Полный пример:

public Import ValidateUploadModel(Import Model)
{
    // DO not allow future dates
    if (Model.CurrMoInfo.CurrMo > DateTime.Now)
    {
        ModelState.AddModelError("CurrMoInfo.CurrMo", "You cannot assign a future date.");
    }
    //Do not allow dates from the same month (we run the processing a month behind)
    if (Model.CurrMoInfo.CurrMo.Month == DateTime.Now.Month)
    {
        ModelState.AddModelError("CurrMoInfo.CurrMo", "You must process a previous month.");
    }

    //Ensure day is last day of a previous month
    if (Model.CurrMoInfo.CurrMo.Day != DateTime.DaysInMonth(Model.CurrMoInfo.CurrMo.Year, Model.CurrMoInfo.CurrMo.Month))
    {
        ModelState.AddModelError("CurrMoInfo.CurrMo", "You must enter the last day of the month.");
    }

    //Do not allow dates older than 12 months back
    if (Model.CurrMoInfo.CurrMo < DateTime.Now.AddMonths(-12))
    {
        ModelState.AddModelError("CurrMoInfo.CurrMo", "Date must not be older than a year.");
    }

    return Model;
}


<div class="card-body">
    @if (Model.StagingCount == 0)
    {
        <input asp-for="CurrMoInfo.CurrMo" type="date" required class="col-lg-12" />
    }
    else
    {
        <input asp-for="CurrMoInfo.CurrMo" type="date" disabled="disabled" required class="col-lg-12" />
    }
    <span asp-validation-for="CurrMoInfo.CurrMo" class="text-danger"></span>
</div>

Дальнейшее чтение: https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation?view=aspnetcore-2.2

P.S. Я не думаю, что этот общий принцип изменился с .NET Framework на .NET Core.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...