DataAnnotation与自定义ResourceProvider

Zak*_*Zak 19 c# asp.net-mvc resources localization

我创建了一个自定义ResourceProvider来从数据库中提取本地化信息.我现在想DataAnnotation用来为模型添加验证.

DataAnnotationhas ErrorMessageResourceTypeErrorMessageResourceName属性但ErrorMessageResourceType只接受System.Type(即编译的资源文件)

有没有办法让DataAnnotation使用自定义ResourceProvider?

EBa*_*arr 6

我意识到这是一个老问题,但想补充一点.我发现自己处于相同的情况,似乎没有关于这个主题的任何文档/博客.尽管如此,我想出了一种使用自定义资源提供程序的方法,但有一点需要注意.需要注意的是,我在MVC应用程序中,所以我仍然HttpContext.GetLocalResourceObject()可用.这是asp.net用于本地化项目的方法.缺少资源对象并不会阻止您编写我们自己的解决方案,即使它是对DB表的直接查询.不过,我认为值得指出.

虽然我对以下解决方案并不十分满意,但它似乎有效.对于我想要使用的每个验证属性,我从所述属性继承并重载IsValid().装饰看起来像这样:

[RequiredLocalized(ErrorMessageResourceType= typeof(ClassBeginValidated), ErrorMessageResourceName="Errors.GenderRequired")]
public string FirstName { get; set; } 
Run Code Online (Sandbox Code Playgroud)

新属性如下所示:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记

  • 您需要使用派生属性而不是标准属性来装饰代码
  • 我正在使用ErrorMessageResourceType传递要验证的类的类型.我的意思是,如果我在客户类并验证FirstName属性,我将传递typeof(客户).我这样做是因为在我的数据库后端我使用完整的类名(namespace + classname)作为键(与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;
    }
}
Run Code Online (Sandbox Code Playgroud)