Проблема
Для лучшего понимания проблемы, возьмем этот кусок HTML сгенерированный ASP.NET MVC при не пройденной валидации текстового поля.
<div class="form-group">
<label for="FirstName">First name</label>
<input class="input-validation-error form-control" data-val="true"
data-val-required="The First name field is required."
id="FirstName" name="FirstName" type="text" value="">
<span class="field-validation-error" data-valmsg-for="FirstName"
data-valmsg-replace="true">The First name field is required.</span>
</div>
Как мы видим, ASP.NET MVC использует свои собственные классы input-validation-error
(для подсветки контрола) и field-validation-error
(для элемента отображающего ошибку).
Без описания этих классов в CSS вышеупомянутый HTML выглядит следующим образом:

Не плохо, но могло бы быть лучше. Bootstrap подсвечивает весь контрол и выделяет так же, с помощью CSS, текст ошибки:

Для этого, согласно документации Bootstrap, нам нужно удостовериться что элемент с ошибкой имеет родительский элемент с классом has-error
, а также элемент для текстового отображения ошибки имеет класс text-danger
. Вот пример как должен выглядеть HTML для его корректной подсветки :
<!-- Класс 'has-error' добавлен к родительскому элементу относительно input -->
<div class="has-error form-group">
<label for="FirstName">First name</label>
<input class="input-validation-error form-control" data-val="true"
data-val-required="The First name field is required."
id="FirstName" name="FirstName" type="text" value="">
<!-- Класс 'text-danger' был добавлен к элементу span -->
<span class="text-danger field-validation-error" data-valmsg-for="FirstName"
data-valmsg-replace="true">The First name field is required.</span>
</div>
Решение
Очевидно что нам нужно просто добавить эти два класса в сгенерированный HTML код, но как мы его будем добавлять будет зависеть от того как реализована валидация.
Без валидации на стороне клиента
Если валидация происходит на стороне сервера мы можем просто добавить нужные нам CSS классы при загрузке страницы:
$(document).ready(function() {
$('.input-validation-error').parents('.form-group').addClass('has-error');
$('.field-validation-error').addClass('text-danger');
});
ASP.NET MVC ненавязчивая валидация
В большинстве случаев используется плагин unobtrusive jQuery validation, и все что нам остается это перехватить события success
и errorPlacement
плагина валидации JQuery:
$(document).ready(function () {
//Будем обрабатывать все формы на странице для которых создан валидатор
var forms = $('form'), formData;
for (var i = 0; i < forms.length; i++) {
formData = $.data(forms[i]);
if (formData.hasOwnProperty("validator")) {
// Сохранить уже существующие обработчки в локальных переменных
var settings = formData.validator.settings,
oldErrorPlacement = settings.errorPlacement,
oldSuccess = settings.success;
settings.errorPlacement = function (label, element) {
// Вызываем старый обработчик
oldErrorPlacement(label, element);
// Добавляем классы Bootstrap
label.parents('.form-group').addClass('has-error');
label.addClass('text-danger');
};
settings.success = function (label) {
// Удаляем has-error класс из <div class="form-group">
// Можно не заботиться об обработке текстового отображения ошибки, так как плагин его автоматичски удалит при ��спешной валидации
label.parents('.form-group').removeClass('has-error');
// Вызываем старый обработчик
oldSuccess(label);
};
}
}
});
Я поместил этот код в отдельный файл MVCToBootstrapValidation.js и добавил в его бандл ~/bundles/jqueryval
который теперь выглядит следующим образом:
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*",
"~/Scripts/MVCToBootstrapValidation.js"));