ASP.NET MVC + FluentValidation + PartialView > нет проверки на стороне клиента

StackOverflow https://stackoverflow.com//questions/22011433

Вопрос

Я использую FluentValidation для проверки моих моделей представлений ASP.NET MVC 5.1 (используя ненавязчивую проверку на стороне клиента по умолчанию).Я регистрирую/создаю свои валидаторы через Ninject (без атрибутов в моделях представления):

FluentValidationModelValidatorProvider.Configure(x => x.ValidatorFactory = new NinjectValidatorFactory(_kernel));
AssemblyScanner.FindValidatorsInAssembly(Assembly.GetExecutingAssembly()).ForEach(match => _kernel.Bind(match.InterfaceType).To(match.ValidatorType));

У меня есть частичное представление, которое часто используется во всем приложении.Это частичное представление имеет свою собственную модель представления.«Основная» модель представления (для всего представления) просто наследуется от этой «частичной» модели представления.

public class IndexViewModel : PersonalInfoViewModel { ... }

Тот же шаблон используется в валидаторах:

public class IndexValidator : PersonalInfoValidator { ... }

Это работает нормально, и проверка на стороне сервера работает так же, как проверка на стороне клиента в «основном» представлении.Но проверка на стороне клиента частичного представления не запускается (нет data-val-* атрибуты в полях ввода).

Мой «основной» взгляд Index.cshtml

@model IndexViewModel
@Html.TextBoxFor(x => x.SomeProperty) // client-side validation works fine

@Html.Partial("PersonalInfo") // client-side validation in the partial view does not work (see below)

Мой частичный взгляд PersonalInfo.cshtml:

@model PersonalInfoViewModel
@Html.TextBoxFor(x => x.FirstName) // client-side validation does not work

Я заметил, что это работает, когда я меняю модель частичного представления на «основную» модель представления:

@model IndexViewModel
@Html.TextBoxFor(x => x.FirstName) // client-side validation works

Поэтому я предполагаю, что где-то при построении проверки на стороне клиента правильный валидатор не подбирается и нет data-val-* атрибуты вводятся в HTML.Но я не могу изменить модель представления в частичном представлении, потому что она используется на нескольких разных страницах с разными «основными» представлениями (хотя все они наследуются от PersonalInfoViewModel).

Есть идеи, как заставить мою проверку на стороне клиента работать в этом случае?

Обновлять

После нескольких часов копания в исходном коде ASP.NET WebStack я обнаружил, что проблема, похоже, возникает в TextBoxFor метод.Там ModelMetaData создается из модели - и где-то там начинает использоваться IndexViewModel вместо PersonalInfoViewModel чтобы получить метаданные для проверки на стороне клиента:

ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Html.GetUnobtrusiveValidationAttributes("FirstName", metadata); // no client-side validation attributes found

Но это генерирует правильные атрибуты проверки на стороне клиента, если я не укажу метаданные явно:

Html.GetUnobtrusiveValidationAttributes("FirstName");

К сожалению, я пока не нашел способа использовать эти знания в свою пользу.

Это было полезно?

Решение

Мне не удалось найти хорошее решение моей проблемы, и я больше не хотел возиться с исходным кодом ASP.NET WebStack, поэтому остановился на уродливом обходном пути:

Я «вручную» ввожу недостающее data-val-* атрибуты при рендеринге полей ввода, например:

@Html.TextBoxFor(x => x.FirstName, Html.GetUnobtrusiveValidationAttributes("FirstName"))

С GetUnobtrusiveValidationAttributes (так называемый автономный) создает правильные атрибуты HTML. Я просто беру их и добавляю в TextBox.Конечно, это не красиво, но это работает, и я могу продолжать свою работу.Если у кого-то есть лучшее решение, я был бы очень рад его услышать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top