1

我可以使用ErrorMessageResourceNameErrorMessageResourceType将规则翻译成我的语言。但是如何翻译类名和属性?

目前,我收到类似Valideringsmeddelande för 'LastName'作为验证消息。我也希望LastName本地化。

4

1 回答 1

2

据我所知,验证应用程序块不使用ErrorMessageErrorMessageResourceName和属性。ErrorMessageResourceType它们包含在 Validation Application Block 5.0 中,因为 VABBaseValidationAttribute现在继承自System.ComponentModel.DataAnnotations.ValidationAttribute. 这些属性在 DataAnnotations' 中定义ValidationAttribute。通过从 DataAnnotations 继承,应用程序和框架可以在不依赖 VAB 的情况下验证模型(例如 ASP.NET MVC 所做的验证)。

您可以做的是使用 VABMessageTemplateResourceName并且MessageTemplateResourceType不使用任何标记并使用特定于属性的文本。例如,将这段完整的文本放入您的资源中:“Valideringsmeddelande för efternamn”(对不起,如果翻译很糟糕;我使用了谷歌翻译)。


更新:

我在图书馆做了一些挖掘,不幸的是没有简单的方法解决这个问题。下面是GetMessageValidator位于Microsoft.Practices.EnterpriseLibrary.Validation.

protected internal virtual string GetMessage(
    object objectToValidate, string key)
{
    return string.Format(CultureInfo.CurrentCulture, 
        this.MessageTemplate, 
        new object[] { objectToValidate, key, this.Tag });
}

如您所见,错误消息是使用MessageTemplateas 格式字符串以及objectToValidate,keyTagas 格式参数生成的。这Tag是您可以在 a 中定义的值,ValidationAttribute因此是静态的,不能是特定于文化的。当您验证一个属性时,提供的key将始终是该属性的名称。该名称将由框架通过反映已验证的类型来提供。

您可以通过定义一个新的Validator并覆盖GetMessage. 通过这种方式,您可以根据资源中的属性名称获取与文化相关的文本。然而,问题是,您必须为您希望使用的每个验证属性创建一个子类,并且对于每个验证属性,您必须继承支持的验证器类。虽然每个属性和每个验证器的代码不应该那么多,但维护这样的代码库仍然非常痛苦。

我认为简单地定义完整的消息会更容易,包括资源中用户友好的语言特定名称。


更新 2:

我想到了一些可能有帮助的东西。当您的应用程序一次只能显示一种语言时,可能会有一种变通方法。如果显示的消息是根据线程的当前文化本地化的,则这不适用于 Web 应用程序,但如果您可以在应用程序的配置文件中配置特定于语言的文本,它可能适用于桌面应用程序。

当您在应用程序的配置文件(这是 VAB 支持的模型)中定义验证规则时,您可以将 Tag 属性与特定于语言的字符串一起使用。

<validation>
  <type name="Company.Application.Domain.Person" 
    defaultRuleset="Default"
    assemblyName="Company.Application.Domain">
    <ruleset name="Default">
      <properties>
        <property name="LastName">
          <validator type="StringLengthValidator" tag="efternamn" 
            upperBound="30" lowerBound="1" 
            lowerBoundType="Inclusive" upperBoundType="Inclusive"
            negated="false" messageTemplate=""
            messageTemplateResourceName=""
            messageTemplateResourceType="" 
            name="String Length Validator" />
        </property>
      </properties>
    </ruleset>
  </type>
</validation>

仔细看看标签tag="efternamn"。当您将 {2} 占位符放在资源中的格式字符串中时,它将被标记中定义的字符串替换。换句话说,这个资源字符串:

Valideringsmeddelande för '{2}'

将导致此验证消息:

Valideringsmeddelande för 'efternamn'

当然,要使其正常工作,您的配置必须本地化。这对于 Web 应用程序来说不是一个好的解决方案。

但是......您还可以更进一步,构建一个IConfigurationSource返回ValidationSettings基于线程当前文化的实例的实现。在这种情况下,您必须在代码中构建配置。以下是如何执行此操作的示例:

public class MyConfigurationSource : IConfigurationSource
{
    private Dictionary<CultureInfo, ValidationSettings> settings =
        new Dictionary<CultureInfo, ValidationSettings>();

    public ConfigurationSection GetSection(string sectionName)
    {
        if (sectionName == ValidationSettings.SectionName)
        {
            var culture = CultureInfo.CurrentCulture;
            lock (this.settings)
            {
                if (!this.settings.ContainsKey(culture))
                {
                    this.settings[culture] = 
                        this.BuildSettingsFor(culture);
                }
                return this.settings[culture];
            }
        }
        return null;
    }

    private ValidationSettings BuildSettingsFor(
        CultureInfo culture)
    {
        // TODO: Build up your configuration here. Example:

        new StringLengthValidatorData("LastName_Smaller100")
        {
            Tag = MyResources.GetValue(
                "Customer.LastName", culture),
            LowerBound = 1,
            LowerBoundType = RangeBoundaryType.Inclusive,
            UpperBound = 100,
            UpperBoundType = RangeBoundaryType.Inclusive
        }
    }
}

你可以提供一个实例,MyConfigurationSource或者ValidationFactory,如果你想要更好的集成,在 VAB 配置中连接这个类型。

但是请注意,目前在代码中构建验证规则需要做很多工作,尤其是因为 VAB(还)没有像样的流畅配置 API(我在这里抱怨过)。我正在编写一个 API 以使其更容易做到这一点(请关注我的博客)。

祝你好运。

于 2010-08-27T12:56:05.043 回答