- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
2012 年 12 月 18 日更新
由于这个问题似乎有很多观点,我应该指出,接受的答案不是我使用的解决方案,但它确实提供了构建解决方案的链接和资源,但是,对我来说请注意,这不是理想的解决方案。我的回答包含 MVC 框架标准部分的 替换 ;并且您应该只在您愿意检查它们是否仍适用于 future 版本时才使用它们(一些私有(private)代码已从官方来源中删除,因为基类中没有足够的可扩展性)。
不过,我可以确认这两个类也适用于 Asp.Net MVC 4 和 3。
也可以为 Asp.Net Web API 框架重复类似的实现,这是我最近完成的。
结束更新
我的类型有很多“标准”验证(必需等),但也有一些自定义验证。
某些验证需要获取服务对象并使用其他属性之一作为键来查找一些较低级别(即“模型层”下)的元数据。然后元数据控制是否需要一个或多个属性以及这些属性的有效格式。
更具体地说,类型是 Card Payment 对象,简化为以下两个相关属性:
public class CardDetails
{
public string CardTypeID { get; set; }
public string CardNumber { get; set; }
}
然后我有一个服务:
public interface ICardTypeService
{
ICardType GetCardType(string cardTypeID);
}
ICardType
然后包含不同的信息位 - 这里的两个关键信息是:
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; }
}
我的 Controller 都能够使用标准模式解析 ICardTypeService
,即
var service = Resolve<ICardTypeService>();
(虽然我应该提到这个调用背后的框架是专有的)
他们通过使用公共(public)界面获得了哪些 yield
public interface IDependant
{
IDependencyResolver Resolver { get; set; }
}
然后,我的框架负责在构造 Controller 实例时为其分配最具体的依赖解析器(由另一个解析器,或由 MVC 标准 Controller 工厂)。最后一个代码块中的 Resolve
方法是围绕此 Resolver
成员的简单包装器。
所以 - 如果我可以为从浏览器收到的付款获取选定的 ICardType
,然后我可以对卡号长度等进行初始检查。问题是,如何解决该服务从我的 IsValid(object, ValidationContext)
覆盖 ValidationAttribute
?
我需要将当前 Controller 的依赖解析器传递给验证上下文。我看到 ValidationContext
都实现了 IServiceProvider
并且有一个 IServiceContainer
的实例 - 很明显我应该能够为我的服务解析器创建一个包装器还实现了其中之一(可能是 IServiceProvider
)。
我已经注意到,在 MVC 框架生成 ValidationContext
的所有地方,服务提供者总是传递 null。
那么我应该在 MVC 管道中的什么时候寻找覆盖核心行为并注入(inject)我的服务提供者?
我应该补充一点,这将不是是我需要做这样的事情的唯一场景 - 所以理想情况下我想要一些我可以应用于管道的东西,以便所有 ValidationContext
配置了当前 Controller 的当前服务提供者。
最佳答案
在 MVC 5.2 上,您可以
利用
窃取 @Andras's answer和 MVC 源代码以及:
DataAnnotationsModelValidatorEx
来自 DataAnnotationsModelValidator
namespace System.Web.Mvc
{
// From https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/DataAnnotationsModelValidator.cs
// commit 5fa60ca38b58, Apr 02, 2015
// Only diff is adding of secton guarded by THERE_IS_A_BETTER_EXTENSION_POINT
public class DataAnnotationsModelValidatorEx : DataAnnotationsModelValidator
{
readonly bool _shouldHotwireValidationContextServiceProviderToDependencyResolver;
public DataAnnotationsModelValidatorEx(
ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute,
bool shouldHotwireValidationContextServiceProviderToDependencyResolver=false)
: base(metadata, context, attribute)
{
_shouldHotwireValidationContextServiceProviderToDependencyResolver =
shouldHotwireValidationContextServiceProviderToDependencyResolver;
}
}
}
public override IEnumerable<ModelValidationResult> Validate(object container)
的基础实现Validate
之后渲染优雅的切口创建上下文:-
public override IEnumerable Validate(object container)
{
// Per the WCF RIA Services team, instance can never be null (if you have
// no parent, you pass yourself for the "instance" parameter).
string memberName = Metadata.PropertyName ?? Metadata.ModelType.Name;
ValidationContext context = new ValidationContext(container ?? Metadata.Model)
{
DisplayName = Metadata.GetDisplayName(),
MemberName = memberName
};
#if !THERE_IS_A_BETTER_EXTENSION_POINT
if(_shouldHotwireValidationContextServiceProviderToDependencyResolver
&& Attribute.RequiresValidationContext)
context.InitializeServiceProvider(DependencyResolver.Current.GetService);
#endif
ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context);
if (result != ValidationResult.Success)
{
// ModelValidationResult.MemberName is used by invoking validators (such as ModelValidator) to
// construct the ModelKey for ModelStateDictionary. When validating at type level we want to append the
// returned MemberNames if specified (e.g. person.Address.FirstName). For property validation, the
// ModelKey can be constructed using the ModelMetadata and we should ignore MemberName (we don't want
// (person.Name.Name). However the invoking validator does not have a way to distinguish between these two
// cases. Consequently we'll only set MemberName if this validation returns a MemberName that is different
// from the property being validated.
string errorMemberName = result.MemberNames.FirstOrDefault();
if (String.Equals(errorMemberName, memberName, StringComparison.Ordinal))
{
errorMemberName = null;
}
var validationResult = new ModelValidationResult
{
Message = result.ErrorMessage,
MemberName = errorMemberName
};
return new ModelValidationResult[] { validationResult };
}
return Enumerable.Empty<ModelValidationResult>();
}
DataAnnotationsModelValidatorProvider
在镇上在您的 Global.asax 执行 DependencyResolver.SetResolver(new AutofacDependencyResolver(container))
之后:-
DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(
typeof(ValidatorServiceAttribute),
(metadata, context, attribute) => new DataAnnotationsModelValidatorEx(metadata, context, attribute, true));
GetService
使用ctor注入(inject)在你的ValidationAttribute
,例如:public class ValidatorServiceAttribute : ValidationAttribute
{
readonly Type _serviceType;
public ValidatorServiceAttribute(Type serviceType)
{
_serviceType = serviceType;
}
protected override ValidationResult IsValid(
object value,
ValidationContext validationContext)
{
var validator = CreateValidatorService(validationContext);
var instance = validationContext.ObjectInstance;
var resultOrValidationResultEmpty = validator.Validate(instance, value);
if (resultOrValidationResultEmpty == ValidationResult.Success)
return resultOrValidationResultEmpty;
if (resultOrValidationResultEmpty.ErrorMessage == string.Empty)
return new ValidationResult(ErrorMessage);
return resultOrValidationResultEmpty;
}
IModelValidator CreateValidatorService(ValidationContext validationContext)
{
return (IModelValidator)validationContext.GetService(_serviceType);
}
}
允许您将它拍在您的模型上:-
class MyModel
{
...
[Required, StringLength(42)]
[ValidatorService(typeof(MyDiDependentValidator),
ErrorMessage = "It's simply unacceptable")]
public string MyProperty { get; set; }
....
}
将它连接到:
public class MyDiDependentValidator : Validator<MyModel>
{
readonly IUnitOfWork _iLoveWrappingStuff;
public MyDiDependentValidator(IUnitOfWork iLoveWrappingStuff)
{
_iLoveWrappingStuff = iLoveWrappingStuff;
}
protected override bool IsValid(MyModel instance, object value)
{
var attempted = (string)value;
return _iLoveWrappingStuff.SaysCanHazCheez(instance, attempted);
}
}
前两者通过以下方式连接:
interface IModelValidator
{
ValidationResult Validate(object instance, object value);
}
public abstract class Validator<T> : IModelValidator
{
protected virtual bool IsValid(T instance, object value)
{
throw new NotImplementedException(
"TODO: implement bool IsValid(T instance, object value)" +
" or ValidationResult Validate(T instance, object value)");
}
protected virtual ValidationResult Validate(T instance, object value)
{
return IsValid(instance, value)
? ValidationResult.Success
: new ValidationResult("");
}
ValidationResult IModelValidator.Validate(object instance, object value)
{
return Validate((T)instance, value);
}
}
我愿意接受更正,但最重要的是,ASP.NET 团队,您愿意接受 PR 以向 DataAnnotationsModelValidator
添加具有此功能的构造函数吗? ?
关于c# - ASP.NET MVC3 : Set custom IServiceProvider in ValidationContext so validators can resolve services,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5218333/
我在大学学习C++时学习了这段代码..后来我在C#中使用了同样的东西...但现在我想在Java中使用它...我在互联网上寻找类似的东西,但我什至不知道如何表达它,以便我得到正确的结果。 所以嗯,请让我
我正在我的 Ruby on Rails Controller 上运行 RSPEC 测试,这是我正在测试的 Controller 操作: Controller 代码: class Customers::
想为我选择的选项卡设置自定义背景,到目前为止,子类化是我自定义 UITAbBar/UITabBarItem 的方式。 问题是:有谁知道(或知道我在哪里可以找到)设置背景的属性是什么? 所选选项卡周围有
您好,我在 commerefacades-beans.xml 中创建了 eProductForm bean,我添加了 ProductData 的自定义属性。 然后在commercewebs
我有两个表:1. 客户2. customer_order 客户表包含客户数据(duh),customer_order 包含所有订单。我可以在 customer.id=customer_order.id
在我的 TableView 中,我有一个 NSMutableArray *currList 的数据源 - 它包含对象 Agent 的对象。我创建了自定义的 TableCell 并正确设置了所有内容。我
是否建议使用自引用泛型继承? public abstract class Entity { public Guid Id {get; set;} public int Version
我正在尝试为我的 Grafana 安装使用自定义文件 ( custom.ini )。不幸的是,这不起作用。 我做了什么: 安装了一台装有 CentOS 7 的虚拟机 添加了 Grafana Yum R
我被分配了两个给定类的作业,一个是抽象父类 Lot.java,另一个是测试类 TestLots.java。我不应该编辑其中任何一个。任务是创建Lot的两个子类,使TestLots中的错误不再是错误。
我是 Botpress 的新手。 我刚刚安装了 Botpress 的最新版本“botpress-ce-v11_0_1-win-x64”。 我浏览了文档,发现了一些关于内容类型、内容元素和内容渲染的解释
我一直在四处寻找,但我还没有找到任何东西,除了 Qt3 的旧文档和 qt 设计器的 3.x 版。 我会举个例子,并不是因为我的项目是 GPL 而不能提供代码,而是为了简单起见。 示例:您正在为您的应用
场景 我有一个自定义规则来验证订单的运费: public class OrderValidator : BaseValidator { private string CustomInfo {
我有用于身份验证的自定义拦截器: @Named("authInterceptor") @Provides @Singleton fun providesAuthIntercep
如果有人没有添加照片,我想显示默认头像图像。我假设我需要在模型或助手中执行自定义 getter。 如果我做 getter,它会看起来像这样吗: def avatar_url "default_ur
我正在使用 Google Search API,但遇到了一些麻烦。这个请求(在 Python 中,使用 requests 库)工作正常 res = requests.get("https://www.
我使用 MSKLC 制作了自定义键盘布局。 我以为我仔细按照说明操作了chose appropriate values对于LOCALENAME和 LOCALID参数。 但是,在通过按 Win+Spac
我正在使用 simpleframework解析 XML 字符串并将其转换为对象。 Serializer serializer = new Persister(); try { Customer
我正在使用 C# 控制台应用程序从 MySql 数据库获取一些数据,但在正确查询时遇到一些问题 现在的情况: SELECT * FROM Customer WHERE EXISTS ( SELECT
我在我的 iPhone 4S 上运行我的应用程序,我正在使用自定义表格 View Controller 和自定义表格 View 单元格,当我将表格 View 向上滑动到空白区域并同样向下滑动到空白区域
我有一个自定义的 JavaScript 变量,它正在检查 eventAction 是什么,这样我就可以知道是否触发一些转换像素。自定义 Javascript 称为“FacebookConversion
我是一名优秀的程序员,十分优秀!