我创建了一个自定义 ResourceProvider
来从数据库中提取本地化信息。我现在想使用 DataAnnotation
向模型添加验证。
DataAnnotation
具有 ErrorMessageResourceType
和 ErrorMessageResourceName
属性,但 ErrorMessageResourceType
只接受 System.Type
(即编译后的资源文件)
有没有办法让 DataAnnotation 使用自定义 ResourceProvider?
最佳答案
我意识到这是一个老问题,但想补充一点。我发现自己处于同样的情况,并且似乎没有关于此主题的任何文档/博客。尽管如此,我想出了一种使用自定义资源提供程序的方法,但有一点需要注意。需要注意的是,我在 MVC 应用程序中,所以我仍然可以使用 HttpContext.GetLocalResourceObject()
。这是 asp.net 用来本地化项目的方法。没有资源对象不会阻止您编写我们自己的解决方案,即使它是对数据库表的直接查询。不过,我认为值得指出。
虽然我对以下解决方案不是很满意,但它似乎有效。对于我想使用的每个验证属性,我继承自所述属性并重载 IsValid()。装饰看起来像这样:
[RequiredLocalized(ErrorMessageResourceType= typeof(ClassBeginValidated), ErrorMessageResourceName="Errors.GenderRequired")]
public string FirstName { get; set; }
新属性如下所示:
public sealed class RequiredLocalized : RequiredAttribute {
public override bool IsValid(object value) {
if ( ! (ErrorMessageResourceType == null || String.IsNullOrWhiteSpace(ErrorMessageResourceName) ) ) {
this.ErrorMessage = MVC_HtmlHelpers.Localize(this.ErrorMessageResourceType, this.ErrorMessageResourceName);
this.ErrorMessageResourceType = null;
this.ErrorMessageResourceName = null;
}
return base.IsValid(value);
}
}
注意事项
- 您需要使用派生属性而不是标准属性来修饰您的代码
- 我正在使用 ErrorMessageResourceType 来传递正在验证的类的类型。我的意思是,如果我在客户类中并验证 FirstName 属性,我将传递 typeof(customer)。我这样做是因为在我的数据库后端中,我使用完整的类名(命名空间 + 类名)作为键(与在 asp.net 中使用页面 URL 的方式相同)。
- MVC_HtmlHelpers.Localize 只是我的自定义资源提供程序的简单包装器
(半盗用的)辅助代码看起来像这样....
public static string Localize (System.Type theType, string resourceKey) {
return Localize (theType, resourceKey, null);
}
public static string Localize (System.Type theType, string resourceKey, params object[] args) {
string resource = (HttpContext.GetLocalResourceObject(theType.FullName, resourceKey) ?? string.Empty).ToString();
return mergeTokens(resource, args);
}
private static string mergeTokens(string resource, object[] args) {
if (resource != null && args != null && args.Length > 0) {
return string.Format(resource, args);
} else {
return resource;
}
}
关于c# - 带有自定义 ResourceProvider 的 DataAnnotation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1848397/