Как использовать аннотации данных для условной проверки модели?
Например, допустим, у нас есть следующая модель (человек и старший):
public class Person
{
[Required(ErrorMessage = "*")]
public string Name
{
get;
set;
}
public bool IsSenior
{
get;
set;
}
public Senior Senior
{
get;
set;
}
}
public class Senior
{
[Required(ErrorMessage = "*")]//this should be conditional validation, based on the "IsSenior" value
public string Description
{
get;
set;
}
}
И следующий вид:
<%= Html.EditorFor(m => m.Name)%>
<%= Html.ValidationMessageFor(m => m.Name)%>
<%= Html.CheckBoxFor(m => m.IsSenior)%>
<%= Html.ValidationMessageFor(m => m.IsSenior)%>
<%= Html.CheckBoxFor(m => m.Senior.Description)%>
<%= Html.ValidationMessageFor(m => m.Senior.Description)%>
Я хотел бы быть условным обязательным полем свойства "Senior.Description" на основе выбора свойства "IsSenior" (true -> обязательно). Как реализовать условную проверку в ASP.NET MVC 2 с аннотациями данных?
c#
asp.net-mvc
forms
validation
Питер Стегнар
источник
источник
Senior
Объект всегда старший, так почему IsSenior может быть ложным в этом случае. Разве вам не нужно, чтобы свойство Person.Senior было нулевым, когда оноPerson.IsSenior
равно false. Или почему бы не реализоватьIsSenior
имущество следующим образом :bool IsSenior { get { return this.Senior != null; } }
.Ответы:
Есть гораздо лучший способ добавить правила условной проверки в MVC3; унаследовать вашу модель
IValidatableObject
и реализоватьValidate
метод:Подробнее читайте в статье Введение в ASP.NET MVC 3 (предварительная версия 1) .
источник
ModelState.IsValid
- а не звонить прямо в ValidateЯ решил это, обработав словарь "ModelState" , который содержится в контроллере. Словарь ModelState включает все элементы, которые необходимо проверить.
Вот решение:
Если вам нужно реализовать условную проверку на основе некоторого поля (например, если A = true, то требуется B), при сохранении сообщений об ошибках на уровне свойств (это неверно для настраиваемых валидаторов, которые находятся на уровне объекта), вы можете добиться этого обрабатывая "ModelState", просто удаляя из него ненужные проверки.
... В каком-то классе ...
... урок продолжается ...
... В некоторых действиях контроллера ...
...
Этим мы добиваемся условной проверки, оставляя все остальное без изменений.
ОБНОВИТЬ:
Это моя последняя реализация: я использовал интерфейс модели и атрибут действия, который проверяет модель, реализующую указанный интерфейс. Интерфейс прописывает метод Validate (ModelStateDictionary modelState). Атрибут действия просто вызывает Validate (modelState) на IValidatorSomething.
Я не хотел усложнять этот ответ, поэтому я не упомянул окончательные детали реализации (которые, в конце концов, имеют значение в производственном коде).
источник
Вчера у меня была такая же проблема, но я сделал это очень чисто, что работает как для проверки на стороне клиента, так и на стороне сервера.
Условие: исходя из значения другого свойства в модели, вы хотите сделать другое свойство обязательным. Вот код
Здесь PropertyName - это свойство, для которого вы хотите сделать свое условие. DesiredValue - это конкретное значение PropertyName (свойства), для которого должно быть проверено другое ваше свойство.
Скажем, у вас есть следующее
Наконец, но не в последнюю очередь, зарегистрируйте адаптер для вашего атрибута, чтобы он мог выполнять проверку на стороне клиента (я поместил его в global.asax, Application_Start)
источник
Я использую этот удивительный nuget, который делает динамические аннотации ExpressiveAnnotations
Вы можете проверить любую логику, о которой можете мечтать:
источник
Вы можете отключить валидаторы условно, удалив ошибки из ModelState:
источник
Спасибо Мерритт :)
Я только что обновил это до MVC 3 на случай, если кто-то сочтет это полезным: условная проверка в ASP.NET MVC 3 .
источник
Теперь существует структура, которая выполняет эту условную проверку (среди других удобных проверок аннотаций данных) из коробки: http://foolproof.codeplex.com/
В частности, обратите внимание на валидатор [RequiredIfTrue ("IsSenior")]. Вы помещаете это непосредственно в свойство, которое хотите проверить, чтобы получить желаемое поведение ошибки проверки, связанной со свойством Senior.
Он доступен в виде пакета NuGet.
источник
Вам необходимо пройти проверку на уровне Person, а не на уровне Senior, или Senior должен иметь ссылку на своего родительского Person. Мне кажется, что вам нужен механизм самопроверки, который определяет валидацию на человеке, а не на одном из его свойств. Я не уверен, но я не думаю, что DataAnnotations поддерживает это из коробки. Что вы можете сделать, создайте свое собственное
Attribute
, основанное наValidationAttribute
этого, можно оформить на уровне класса, а затем создать настраиваемый валидатор, который также позволяет запускать эти валидаторы уровня класса.Я знаю, что Validation Application Block сразу поддерживает самопроверку, но у VAB довольно крутая кривая обучения. Тем не менее, вот пример использования VAB:
источник
У меня была такая же проблема, мне нужна была модификация атрибута [Required] - поле make необходимо в зависимости от http-запроса. Решение было похоже на ответ Дэна Хунекса, но его решение не работало правильно (см. Комментарии). Я не использую ненавязчивую проверку, просто MicrosoftMvcValidation.js из коробки. Вот. Реализуйте свой настраиваемый атрибут:
Затем вам нужно реализовать своего настраиваемого поставщика, чтобы использовать его в качестве адаптера в вашем global.asax.
И измените свой global.asax строкой
и вот это
Главное преимущество для меня в том, что мне не нужно кодировать собственный валидатор клиента, как в случае ненавязчивой валидации. он работает так же, как [Обязательно], но только в тех случаях, когда вы хотите.
источник
DataAnnotationsModelValidator
была именно тем, что мне нужно было увидеть. Спасибо.Ознакомьтесь с условной проверкой Саймона Инса в MVC .
Я работаю над его примером проекта прямо сейчас.
источник
Типичное использование для условного удаления ошибки из состояния модели:
Пример:
В вашем примере оставьте все как есть и добавьте логику, предложенную в действие вашего контроллера. Я предполагаю, что ваша ViewModel, переданная в действие контроллера, содержит объекты Person и Senior Person с данными, заполненными в них из пользовательского интерфейса.
источник
Я использую MVC 5, но вы можете попробовать что-то вроде этого:
В вашем случае вы бы сказали что-то вроде «IsSenior == true». Тогда вам просто нужно проверить правильность вашего действия с публикацией.
источник