在MVC中,我可以创建一个可以采用依赖关系的模型验证器.我通常使用FluentValidation.例如,这允许我检查帐户注册是否未使用电子邮件地址(注意:这是一个简化的示例!):
public class RegisterModelValidator : AbstractValidator<RegisterModel> {
private readonly MyContext _context;
public RegisterModelValidator(MyContext context) {
_context = context;
}
public override ValidationResult Validate(ValidationContext<RegisterModel> context) {
var result = base.Validate(context);
if (context.Accounts.Any(acc => acc.Email == context.InstanceToValidate.Email)){
result.Errors.Add(new ValidationFailure("Email", "Email has been used"));
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
使用FluentValidation的Web API不存在此类集成.已经有夫妇的尝试,在这一点,但也没有解决的依赖注入方面,只有静态验证工作.
这很困难的原因是由于MVC和Web API之间的ModelValidatorProvider和ModelValidator的实现不同.在MVC中,这些是按请求实例化的(因此注入上下文很容易).在Web API中,它们是静态的,ModelValidatorProvider为每种类型维护ModelValidators的缓存,以避免对每个请求进行不必要的反射查找.
我一直试图自己添加必要的集成,但一直试图获得依赖范围.相反,我想我会退后一步,询问是否还有其他问题的解决方案 - 如果有人提出了执行模型验证的解决方案,可以注入依赖关系.
我不想在Controller中执行验证(我使用ValidationActionFilter来保持这一点),这意味着我无法从控制器的构造函数注入中获得任何帮助.
我已经设置了一个自定义提供程序,允许从数据存储而不是静态代码中设置验证属性.在我的.NET MVC 4项目中使用客户端验证非常有用,但我无法让服务器端验证工作.
CustomModelValidatorProvider .cs:
public class CustomModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
protected override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable attributes)
{
// set attributes from datastore here
return base.GetValidators(metadata, context, attributes);
}
}
在我的Global.asax.cs中,我有:
protected void Application_Start()
{
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new CustomModelValidatorProvider());
}
在Web API方法中,我有:
var validationResultList = new List();
bool valid = Validator.TryValidateObject(myModelObject, new ValidationContext(myModelObject, null, null), validationResultList, true);
在这里,有效总是如此.即使Jquery客户端验证显示错误.在服务器端,我的自定义提供程序不用于应用数据注释.当我在GetValidators()中设置断点时,在创建View时调用它并正确显示客户端验证器,但是当模型绑定到控制器时不会再次调用它.
我错过了一步吗?任何帮助是极大的赞赏!
UPDATE
当对象发布到Controller时,自定义验证器可以正常工作,但是当发布到ApiController时不会被触发.
c# asp.net-mvc model-validation data-annotations asp.net-web-api