TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2338 2.75K
День 1934. #ЗаметкиНаПолях #Frontend
ASP.NET Unobtrusive Validation. Группируем Сообщения об Ошибках
Сегодня пост из личного опыта. Немного легаси и немного «попрограммируем» на HTML+CSS 😊
Не знаю, как дела обстоят в UI фреймворках, таких, как React или Vue, т.к. не знаком с ними, но мы в компании до сих пор используем старый добрый HTML и jQuery. В том числе для валидации форм используется встроенная в ASP.NET jQuery Unobtrusive Validation. Она позволяет проверять формы на клиенте без написания логики валидации на JS. То есть в модели используются стандартные атрибуты Data Annotations.
Например, для модели:
public class MyModel
{
[Required]
public string Name { get; set; }
}

И формы
<form method="post">
Email: <input asp-for="Name" /> <br />
<span asp-validation-for="Name"></span>
…
</form>

Будет сгенерирован следующий HTML код:
<form method="post">
Name: <input name="Name" id="Name" type="text" value=""
data-val-required="The Name field is required."
data-val="true"><br>
<span class="field-validation-valid" data-valmsg-replace="true"
data-valmsg-for="Name"></span>
…
</form>

И эта форма автоматически будет проверяться средствами JS согласно этим атрибутам на клиенте без отправки формы на сервер. В случае непрошедшей валидации в элемент <span> будет добавляться соответствующее сообщение об ошибке, а его класс сменится с field-validation-valid на field-validation-error. Можно сделать так, что все ошибки формы будут выдаваться в одном месте (validation summary), либо для каждого поля в отдельности (как в этом случае).

Конечно, если требуется нестандартная валидация, можно как написать свой атрибут валидации, так и добавить в JS валидатор для него.

Мне же требовалось, чтобы только 2 поля формы поля проверялись в паре и выдавали одно сообщение об ошибке на двоих в одном и том же месте, даже если оба поля не пройдут валидацию. Проблема подробно описана на StackOverflow. Там у автора была дата рождения, у меня аналогично двумя выпадающими списками выбирались месяц и год истечения срока кредитной карты.

Предложенное там решение в виде написания собственного атрибута (плюс валидатора в JS) показалось мне чересчур сложным для такого, вроде бы, тривиального случая. Поэтому решено было действовать методами фронтэнда.

В общем то, решение довольно простое. Размещаем оба поля и оба валидатора для них:
<form method="post">
Expires:
<select asp-for="Month" asp-items="Model.Months"></select> /
<select asp-for="Year" asp-items="Model.Years"></select>
<div class="val-msg-group">
<span asp-validation-for="Month"></span>
<span asp-validation-for="Year"></span>
</div>
…
</form>

В этом случае, если оба поля будут пустыми, будут выведены оба сообщения об ошибке, по одному для каждого. Это решается просто сокрытием второго сообщения средствами CSS:
.val-msg-group .field-validation-error ~ .field-validation-error {
display: none;
}

Здесь мы внутри блока val-msg-group скрываем всех потомков, за которыми следует элемент с тем же классом field-validation-error. То есть, первое сообщение об ошибке будет показано (для какого бы поля оно ни было), а остальные будут спрятаны. См. видео ниже.

В общем, думаю, что приём будет полезен и в других UI фреймворках, работающих по подобному принципу.
  • 👍 5
  • 👎 1
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →