Валидация блока приложения и локализация модели

Я могу использовать ErrorMessageResourceName и ErrorMessageResourceType для перевода правил на мой язык. Но как мне перевести имя класса и свойства?

В настоящее время я получаю что-то вроде Valideringsmeddelande för 'LastName' в качестве сообщения проверки. Я хочу, чтобы LastName тоже был локализован.

1
задан Steven 31 August 2010 в 08:09
поделиться

1 ответ

Насколько мне известно, свойства ErrorMessage, ErrorMessageResourceName и ErrorMessageResourceType не используются блоком приложения проверки. Они включены в блок приложения проверки 5.0, поскольку BaseValidationAttribute VAB теперь наследуется от System.ComponentModel.DataAnnotations.ValidationAttribute. Эти свойства определены в атрибуте ValidationAttribute DataAnnotations. Наследуя от DataAnnotations, приложения и платформы могут проверять модель без зависимости от VAB (например, проверку, которую выполняет ASP.NET MVC).

Что вы можете сделать, так это использовать MessageTemplateResourceName и MessageTemplateResourceType VAB, не использовать маркеры и использовать текст, специфичный для свойства. Например, поместите этот полный текст в свой ресурс: «Valideringsmeddelande for efternamn» (извините, если перевод дерьмовый, я использовал Google переводчик).


Обновление:

Я немного покопался в библиотеке, и, к сожалению, нет простого способа обойти это. Ниже приведен код метода GetMessage, определенного в базовом классе Validator, расположенном в 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 });
}

Как видите, сообщение об ошибке генерируется с использованием MessageTemplate в качестве строки формата вместе с objectToValidate, key и Tag в качестве аргументов форматирования.Tag — это значение, которое можно определить в ValidationAttribute, поэтому оно является статическим и не может быть привязано к культуре. Когда вы проверяете свойство, предоставленный ключ всегда будет именем этого свойства. Это имя будет предоставлено платформой путем отражения проверенного типа.

Вы можете сделать имя более удобным для пользователя и специфичным для языка, определив новый Validator и переопределив GetMessage. Таким образом, вы можете получить текст, зависящий от культуры, на основе имени свойства из ресурса. Однако проблема заключается в том, что вам придется создать подкласс для каждого атрибута проверки, который вы хотите использовать, и для каждого атрибута проверки вы должны наследовать поддерживающий класс проверки. Хотя это не должно быть так много кода для каждого атрибута и для каждого валидатора, все равно будет очень сложно поддерживать такую ​​базу кода.

Я думаю, что было бы проще просто определить в ресурсе полное сообщение, включая понятное для пользователя имя для конкретного языка.


Обновление 2:

Я подумал о том, что могло бы помочь. Когда ваше приложение должно одновременно отображать только один язык, может быть обходной путь. Это не будет работать для веб-приложений, если отображаемые сообщения локализованы в зависимости от текущей культуры потока, но может работать для настольных приложений, если вы можете настроить тексты для конкретного языка в файле конфигурации приложения.

Когда вы определяете правила проверки в файле конфигурации приложения (который является моделью, поддерживаемой 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'

Конечно, чтобы это работало, ваша конфигурация должна быть локализована. Это не было бы хорошим решением для веб-приложений.

Но... вы также можете сделать еще один шаг и создать реализацию 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 (пока) нет приличного API для плавной настройки (я жаловался на это здесь). Я нахожусь в процессе написания API, который значительно упрощает это (следите за моим блогом).

Удачи.

2
ответ дан 2 September 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: