Я могу использовать ErrorMessageResourceName и ErrorMessageResourceType для перевода правил на мой язык. Но как мне перевести имя класса и свойства?
В настоящее время я получаю что-то вроде Valideringsmeddelande för 'LastName' в качестве сообщения проверки. Я хочу, чтобы LastName тоже был локализован.
Насколько мне известно, свойства 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
. Таким образом, вы можете получить текст, зависящий от культуры, на основе имени свойства из ресурса. Однако проблема заключается в том, что вам придется создать подкласс для каждого атрибута проверки, который вы хотите использовать, и для каждого атрибута проверки вы должны наследовать поддерживающий класс проверки. Хотя это не должно быть так много кода для каждого атрибута и для каждого валидатора, все равно будет очень сложно поддерживать такую базу кода.
Я думаю, что было бы проще просто определить в ресурсе полное сообщение, включая понятное для пользователя имя для конкретного языка.
Я подумал о том, что могло бы помочь. Когда ваше приложение должно одновременно отображать только один язык, может быть обходной путь. Это не будет работать для веб-приложений, если отображаемые сообщения локализованы в зависимости от текущей культуры потока, но может работать для настольных приложений, если вы можете настроить тексты для конкретного языка в файле конфигурации приложения.
Когда вы определяете правила проверки в файле конфигурации приложения (который является моделью, поддерживаемой 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, который значительно упрощает это (следите за моим блогом).
Удачи.