2013-05-03 3 views
2

Я использую Foolproof Validation, поэтому я могу использовать атрибуты [RequiredIf] в моей модели просмотра. Проблема в том, что я хотел бы инициировать проверку в моем коде, используя ту же логику вне контроллера.Вручную запускать надежную проверку

Я попытался создать свой собственный контекст проверки и использовать Validatior.TryValidateObject; однако он не работает с помощью проверки подлинности RequiredIf Foolproof. Есть ли способ взять мою модель и проверить ее, кроме как передать ее контроллеру?

Я использую неправильный подход?

Вот мой код:

var draftModel = _draftHelper.LoadDraft(draftId); 

var validationResults = new List<ValidationResult>(); 

var vc = new ValidationContext(draftModel, null, null); 

var isValidDraft = Validator.TryValidateObject(draftModel, vc, 
               validationResults, true); 

И Я получаю ошибку на линии TryValidateObject

System.NotImplementedException: Метод или операция не реализована.

ответ

3

Я думаю, что лучше использовать FluentValidation, а не проверку подлинности. Я лично считаю, что Fluent лучше, чем атрибуты :).

Используя FluentValidation, вы также можете проверить свою модель без использования контроллера.

DraftVM draft = draftRepository.Get(draftId); 

var DraftValidator validator = new DraftVMValidator(); 
ValidationResult results = validator.Validate(draft); 

public class DraftVMValidator : AbstractValidator<DraftViewModel> 
{ 
     public DraftVMValidator() 
     { 

     RuleFor(vm => vm.OptionalField) 
      .Must(BeFilledIfNameNotEmpty) 
      .WithMessage("Optional Field required because you filled out Name field"); 
     } 


     public bool BeFilledIfNameNotEmpty(DraftVM viewModel) 
     { 
      return !string.IsNullOrWhiteSpace(viewModel.Name); 
     } 

} 

Это НЕ даст вам исключение System.NotImplemented.

Этот валидатор СУХОЙ, потому что вы также можете подключить его к ASP.NET MVC Validation.
Вы можете просто вызвать следующий код в Global.asax или App_Start и т. Д. Один валидатор для всех, привяжите его к MVC Model Validation или используйте его в любом обычном приложении.

FluentValidationModelValidatorProvider.Configure(); // This will bind it for you 

Если вы используете Инверсия управления контейнера, как Ninject, FluentValidation также имеет плагин для работы с этим. Более подробная информация содержится в их документации по ссылке, приведенной выше.

У меня есть довольно большой пример проекта в моем Github, если вы хотите увидеть больше примеров этого Validator вместо FoolProof. Example Validators with ASP.NET MVC 4

+0

Спасибо @Patrick Маги, который может быть правильный подход. Я не понял, что Fluent также поддерживает проверку на стороне клиента. Я проверю его сегодня, и если он также предоставит пользовательскую проверку на стороне клиента, то это будет мой ответ. –

+0

Вы также можете уйти с FluentValidation, используя REMOTE-проверку для таких вещей, как электронные письма, которые должны быть уникальными, используя Ajax для проверки без необходимости повторной отправки формы. В моем проекте также есть пример. Поскольку функция Predicate (Must) по умолчанию не поддерживает удаленное подтверждение. Тем не менее, вы можете создавать собственные связующие. –

+0

Спасибо @Patrick Magee, я проверил ваше решение, и он отлично работает. Это решило мою проблему. Что касается [Remote], который будет работать; однако, по-прежнему, по-прежнему предпочитаю настраиваемые валидаторы клиентской стороны. –

2

Вы должны позволить рамки MVC обеспечить свой валидатор вместо использования Validator.TryValidateObject, как показано ниже:

var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => viewModelToValidate, viewModelToValidate.GetType()); 
var compositeValidator = ModelValidator.GetModelValidator(modelMetadata, controller.ControllerContext); 
foreach (ModelValidationResult result in compositeValidator.Validate(null)) 
{ 
    validationResults.Add(new ValidationResult(result.Message, new List<string> { result.MemberName })); 
} 
Смежные вопросы