Asp.Net MVC3:在ValidationContext设置自定义的IServiceProvider这样的验证可以解决服务 [英] Asp.Net MVC3: Set custom IServiceProvider in ValidationContext so validators can resolve services
问题描述
更新18 2012年12月的
Update 18th December 2012
由于这个问题似乎得到了不少意见,我要指出的是,公认的答案是不是我用的解决方案,但它确实提供链接和资源构建一个解决方案,但是,我的没关系,不是理想的解决方案。我的回答包含的 替换的 的MVC框架的标准件;你应该只使用这些,如果你是舒适的检查,他们仍然对未来版本的工作,(一些民营code的拆出来的官方消息,因为没有足够的可扩展性,在基类)。的
不过,我可以肯定,这也是这两个班Asp.Net MVC 4以及工作作为3。的
也可以重复类似的实现了Asp.Net的Web API框架为好,这是我最近做了。的
末更新的
End update
我有了很多'标准'验证(需要等)一类,但也有点自定义的验证也是如此。
I have a type that has a lot of 'standard' validation (required etc) but also a bit of custom validation as well.
一些这方面的验证需要抓住保持一个服务对象,并寻找一些较低级别的(即下的Model层),使用的其他属性的重要一个元数据。该元数据然后控制一个或多个属性是否需要以及有效格式为这些属性
Some of this validation requires grabbing hold of a service object and looking up some lower-level (i.e. 'beneath' the Model layer) meta data using one of the other properties as a key. The meta data then controls whether one or more properties are required as well as valid formats for those properties.
要更具体 - 类型是卡支付对象,简化为两个属性的问题如下:
To be more concrete - the type is a Card Payment object, simplified to two of the properties in question as follows:
public class CardDetails
{
public string CardTypeID { get; set; }
public string CardNumber { get; set; }
}
然后我有一个服务:
I then have a service:
public interface ICardTypeService
{
ICardType GetCardType(string cardTypeID);
}
ICardType
则包含不同的信息比特 - 两个在这里,是至关重要的存在:
ICardType
then contains different bits of information - the two here that are crucial being:
public interface ICardType
{
//different cards support one or more card lengths
IEnumerable<int> CardNumberLengths { get; set; }
//e.g. - implementation of the Luhn algorithm
Func<string, bool> CardNumberVerifier { get; set; }
}
我的控制器都必须解决能力的 ICardTypeService
使用标准模式,即
var service = Resolve<ICardTypeService>();
(虽然我应该指出,这个调用后面的框架是私有的)
(Although I should mention that the framework behind this call is proprietary)
,他们通过使用通用接口获得
Which they gain via the use of a common interface
public interface IDependant
{
IDependencyResolver Resolver { get; set; }
}
我的框架然后负责分配最特异性依赖解析器可用于控制器实例,当它被构造的(通过另一个分解器,或通过了MVC标准控制器工厂)。这解决
在过去,只有一个code座的方法是解决此旋
成员的简单包装。
My framework then takes care of assigning the most-specific dependency resolver available for the controller instance when it is constructed (either by another resolver, or by the MVC standard controller factory). That Resolve
method in the last-but one code block is a simple wrapper around this Resolver
member.
所以 - 如果我能抢到选择 ICardType
用于从浏览器收到的付款,然后我就可以在卡号长度进行初步检查等问题如何从我的 IsValid的(对象,ValidationContext)
覆盖 ValidationAttribute
的覆盖范围内解决服务?
So - if I can grab the selected ICardType
for the payment that is received from the browser, I can then perform initial checks on card number length etc. The issue is, how to resolve the service from within my override of IsValid(object, ValidationContext)
override of ValidationAttribute
?
我需要通过电流控制器的依赖解析器传递到验证环境。我看到 ValidationContext
这两个工具的IServiceProvider
并具有 IServiceContainer的实例
- 这么清楚,我应该能够创建一个包装我也实现了其中的一个服务解析器(大概的IServiceProvider
)
I need to pass through the current controller's dependency resolver to the validation context. I see that ValidationContext
both implements IServiceProvider
and has an instance of IServiceContainer
- so clearly I should be able to create a wrapper for my service resolver that also implements one of those (probably IServiceProvider
).
我已经注意到,在一个 ValidationContext
是由MVC框架产生的所有地方,服务提供商的总是的传递空。
I've already noted that in all places where a ValidationContext
is produced by the MVC framework, the service provider is always passed null.
那么在什么时候,在MVC管道我应该寻找替代的核心行为,并注入我的服务提供商?
So at what point in the MVC pipeline should I be looking to override the core behaviour and inject my service provider?
我要补充一点,这将的没有的是唯一的场景,我需要做这样的事情 - 所以理论上讲,我想这一点我可以向管道,让所有 ValidationContext
s的配置与当前服务提供商电流控制器。
I should add that this will not be the only scenario in which I need to do something like this - so ideally I'd like something which I can apply to the pipeline so that all ValidationContext
s are configured with the current service provider for the current controller.
推荐答案
你有没有想过创建模型验证,使用modelValidatorProvider,而不是使用验证属性?这样,你不依赖于ValidationAttribute但可以创建自己的验证实现(这除了工作中存在的DataAnnotations验证)。
Have you thought about creating a model validator, using a modelValidatorProvider, instead of using validation attributes? This way you're not dependant on ValidationAttribute but can create your own validation implementation (this will work in addition the existing DataAnnotations validation).
的http://msdn.microsoft.com/en-us/library/system.web.mvc.modelvalidatorprovider.aspx
<一个href="http://dotnetslackers.com/articles/aspnet/Experience-ASP-NET-MVC-3-Beta-the-New-Dependency-Injection-Support-Part2.aspx#s10-new-support-for-validator-provider" rel="nofollow">http://dotnetslackers.com/articles/aspnet/Experience-ASP-NET-MVC-3-Beta-the-New-Dependency-Injection-Support-Part2.aspx#s10-new-support-for-validator-provider
<一个href="http://dotnetslackers.com/articles/aspnet/Customizing-ASP-NET-MVC-2-Metadata-and-Validation.aspx#s2-validation" rel="nofollow">http://dotnetslackers.com/articles/aspnet/Customizing-ASP-NET-MVC-2-Metadata-and-Validation.aspx#s2-validation
这篇关于Asp.Net MVC3:在ValidationContext设置自定义的IServiceProvider这样的验证可以解决服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!