2

我正在使用万无一失的验证,所以我可以在我的视图模型上使用 [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:方法或操作未实现。

4

2 回答 2

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

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

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

如果您使用像 Ninject 这样的控制反转容器,FluentValidation 也有一个插件可以使用它。上面提供的链接中提供了更多关于他们的文档的信息。

如果你想看到更多关于这个 Validator 的例子而不是 FoolProof,我在我的 Github 中有一个相当大的项目例子。使用 ASP.NET MVC 4 的示例验证器

于 2013-05-11T06:04:42.113 回答
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 }));
}
于 2013-07-25T07:29:38.650 回答