Валидация блока приложения и локализация модели - PullRequest
1 голос
/ 27 августа 2010

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

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

1 Ответ

2 голосов
/ 27 августа 2010

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

Что вы можете сделать, это использовать VAB MessageTemplateResourceName и MessageTemplateResourceType, не использовать маркеры и использовать текст, относящийся к свойству. Например, поместите этот полный текст в свой ресурс: «Valideringsmeddelande för 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, поэтому оно является статическим и не может зависеть от конкретной культуры. При проверке свойства указанным key всегда будет имя этого свойства. Это имя будет предоставлено платформой, отражая проверенный тип.

Вы можете сделать имя более удобным для пользователя и конкретного языка, определив новый 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.

Обратите внимание, однако, что создание правил проверки в коде в настоящее время является большой работой, особенно потому, что VAB (пока) не имеет приличного свободного API конфигурации (я жаловался на это здесь ). Я нахожусь в процессе написания API, который делает это намного проще (следите за моим блогом для этого).

Удачи.

...