手动触发万无一失的验证

时间:2013-05-03 00:44:14

标签: asp.net-mvc foolproof-validation

我正在使用Foolproof Validation,因此我可以在视图模型上使用[RequiredIf]属性。问题是我想在我的代码中使用控制器外部的相同逻辑触发验证。

我尝试创建自己的验证上下文并使用Validatior.TryValidateObject;但是,它使用Foolproof的自定义RequiredIf验证器失败了。有没有办法获取我的模型并验证它而不是将其传递给控制器​​?

我使用了错误的方法吗?

这是我的代码:

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:方法或操作不是   实现。

2 个答案:

答案 0 :(得分:3)

我认为更好的方法是使用FluentValidation,而不是万无一失的验证。我个人认为Fluent比属性更好:)。

使用FluentValidation,您还可以在不使用Controller的情况下验证模型。

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异常。

此验证程序是DRY,因为您还可以将其插入ASP.NET MVC验证 您可以在Global.asax或App_Start等中调用以下代码。一个验证器,将其绑定到MVC模型验证或在任何正常应用程序中使用它。

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

如果你像Ninject一样使用Inversion of Control容器,FluentValidation也有一个插件可以使用它。有关其文档的更多信息,请参见上面提供的链接。

如果你想看到这个Validator的更多例子而不是FoolProof,我在我的Github中有一个非常大的项目示例。 Example Validators with ASP.NET MVC 4

答案 1 :(得分:2)

您需要让MVC框架提供您的Validator,而不是使用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 }));
}
相关问题