ASP.NET MVC 3:在需要模型外部信息时验证模型

Kal*_*son 11 validation asp.net-mvc-3

当需要模型外部的信息以进行验证时,验证模型的好方法是什么?例如,请考虑以下模型:

public class Rating {
    public string Comment { get; set; }
    public int RatingLevel { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,系统管理员可以设置RatingLevels需要注释的对象.这些设置可通过设置服务获得.

因此,为了完全验证模型,我需要外部信息,在这种情况下是设置服务.

到目前为止我考虑过以下几点:

  1. 将服务注入模型.DefaultModelBinder使用System.Activator创建对象,因此它不经过正常的依赖解析器,并不会产生一个新的模型绑定(我不能注入服务到模型中,除了这,不觉得自己是正确的如何去做).
  2. 将服务注入注释.我还不确定这是可能的,但很快就会进行调查.它仍然感觉笨拙.
  3. 使用自定义模型绑定器.显然我可以实现OnPropertyValidating来进行自定义属性验证.到目前为止,这似乎是最优选的,但我还不确定如何做到这一点.

哪种方法,无论上述与否,最适合此类验证问题?

Kal*_*son 15

选项1不合适.它唯一可行的方法是通过服务定位器反模式来引入依赖.

选项2 不起作用.虽然由于C#属性要求,我无法看到这是如何可能的,但这是可能的.请参阅以下参考资料:

选项3:我之前不知道这一点,但似乎是一种非常强大的编写验证器的方法是使用ModelValidator类和相应的ModelValidatorProvider.

首先,您创建自定义ModelValidatorProvider:

public class CustomModelValidatorProvider : ModelValidatorProvider
{
    public CustomModelValidatorProvider(/* Your dependencies */) {}

    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {
        if (metadata.ModelType == typeof(YourModel))
        {
            yield return new YourModelValidator(...);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ASP.NET MVC的IDependencyResolver将尝试解析上述提供程序,因此只要它在您的IoC容器中注册,您就不需要执行任何其他操作.然后是ModelValidator:

public class EntryRatingViewModelValidatorMvcAdapter : ModelValidator
{
    public EntryRatingViewModelValidatorMvcAdapter(
            ModelMetadata argMetadata,
            ControllerContext argContext)
                : base(argMetadata, argContext)
    {
        _validator = validator;
    }


    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        if (/* error condition */)
        {
            yield return new ModelValidationResult
              {
                MemberName = "Model.Member",
                Message = "Rating is required."
              };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

由于提供程序是通过提取程序检索的IDependencyResolver,并且提供程序可以完全控制返回的ModelValidators,因此我可以轻松地注入依赖项并执行必要的验证.


Ben*_*ter 5

您可以尝试流畅的验证.它支持asp.net mvc和DI,因此您可以将外部服务注入验证器.