依赖注入在网页API验证 [英] Dependency-Injected Validation in Web API
问题描述
在MVC中,我可以创建一个模型验证可以采取的依赖关系。我通常使用FluentValidation这一点。这让我,比如,检查,一个电子邮件地址尚未使用的帐号注册(注:这是一个简单的例子!):
In MVC, I can create a Model Validator which can take Dependencies. I normally use FluentValidation for this. This allows me to, for example, check on account registration that an e-mail address hasn't been used (NB: This is a simplified example!):
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;
}
}
没有这种整合存在是为了与FluentValidation的Web API。曾有的<一个一个夫妇 href=\"https://fluentvalidation.$c$cplex.com/SourceControl/network/forks/paulduran/webapisupportv2/contribution/3940\">attempts这个,但也已经攻克了依赖注入方面,只有静态验证工作。
No such integration exists for Web API with FluentValidation. There have been a couple of attempts at this, but neither have tackled the Dependency Injection aspect and only work with static validators.
究其原因,这是困难的是由于MVC和Web API之间实现ModelValidatorProvider和ModelValidator的不同。在MVC中,这些都是每个请求实例化(因此注入上下文很简单)。在网页API,它们是静态的,而ModelValidatorProvider保持每个类型ModelValidators的高速缓存,以避免在每次请求不必要的反射查找。
The reason this is difficult is due to the different in implementation of ModelValidatorProvider and ModelValidator between MVC and Web API. In MVC, these are instantiated per-request (hence injecting a context is easy). In Web API, they are static, and the ModelValidatorProvider maintains a cache of ModelValidators per type, to avoid unnecessary reflection lookups on every request.
我一直在尝试添加必要的整合自己,但一直卡住试图获得依赖范围。相反,我以为我会退后一步,询问是否有任何其他解决问题的办法 - 如果有人想出了一个解决方案来进行模型验证依赖哪里可以注射
I've been trying to add the necessary integration myself, but have been stuck trying to obtain the Dependency Scope. Instead, I thought I'd step back and ask if there any other solutions to the problem - if anyone has come up with a solution to performing Model Validation where dependencies can be injected.
我不希望到控制器内执行验证(我使用的是 ValidationActionFilter 保持这种独立的),这意味着我无法从控制器的构造器注入任何帮助。
I do NOT want to perform the validation within the Controller (I am using a ValidationActionFilter to keep this separate), which means I can't get any help from the constructor injection of the controller.
推荐答案
我终于得到这个工作,但它是一个有点bodge的。正如前面提到的,ModelValidatorProvider将保持周围所有验证的辛格尔顿实例,所以这是完全不适合。相反,我使用的过滤器来运行我自己的验证,通过对立的建议。该过滤器可以访问 IDependencyScope
,可以整齐实例验证。
I've finally got this to work, but it's a bit of a bodge. As mentioned earlier, the ModelValidatorProvider will keep Singleton instances of all Validators around, so this was completely unsuitable. Instead, I'm using a Filter to run my own validation, as suggested by Oppositional. This filter has access to the IDependencyScope
and can instantiate validators neatly.
中的过滤器,我经过 ActionArguments
,并通过审定通过他们。验证code被复制出来的网页API运行源为 DefaultBodyModelValidator
,修改,查找在 DependencyScope $ c中的验证$ C>。
Within the Filter, I go through the ActionArguments
, and pass them through validation. The validation code was copied out of the Web API runtime source for DefaultBodyModelValidator
, modified to look for the Validator within the DependencyScope
.
最后,为了与 ValidationActionFilter
,你需要的确保您的过滤器在一个特定的顺序执行。
Finally, to make this work with the ValidationActionFilter
, you need to ensure that your filters are executed in a specific order.
我打包我的解决方案了在 github上,用版本上的NuGet。
I've packaged my solution up on github, with a version available on nuget.
这篇关于依赖注入在网页API验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!