1

ErrorMessageResourceNameErrorMessageResourceTypeを使用して、ルールを自分の言語に翻訳できます。しかし、クラス名とプロパティをどのように翻訳すればよいですか?

現在、検証メッセージとしてValideringsmeddelandeför'LastName'のようなものが表示されます。LastNameもローカライズしたいです。

4

1 に答える 1

2

私の知る限りErrorMessage、、、、ErrorMessageResourceNameおよびErrorMessageResourceTypeプロパティは検証アプリケーションブロックによって使用されません。BaseValidationAttributeVABはからを継承するようになったため、これらはValidation ApplicationBlock5.0に含まれていSystem.ComponentModel.DataAnnotations.ValidationAttributeます。これらのプロパティは、DataAnnotationsで定義されていますValidationAttribute。DataAnnotationsから継承することにより、アプリケーションとフレームワークは、VABに依存することなくモデルを検証できます(たとえば、ASP.NET MVCが行う検証など)。

あなたができることはVABを使用することでMessageTemplateResourceNameありMessageTemplateResourceType、マーカーを使用せず、プロパティに固有のテキストを使用します。たとえば、この完全なテキストをリソースに入れてください:「Valideringsmeddelandeförefternamn」(翻訳がくだらない場合は申し訳ありません。私はGoogle翻訳を使用しました)。


アップデート:

私は図書館を掘り下げましたが、残念ながらこれを回避する簡単な方法はありません。以下は、にある基本クラスでGetMessage定義されているメソッドのコードです。ValidatorMicrosoft.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、、、keyおよびTagフォーマット引数を使用して生成されます。はでTag定義できる値であるValidationAttributeため、静的であり、カルチャ固有にすることはできません。プロパティを検証する場合、提供されるkeyのは常にそのプロパティの名前です。この名前は、検証されたタイプを反映することにより、フレームワークによって提供されます。

新しい名前を定義し、Validatorをオーバーライドすることで、名前をよりユーザーフレンドリーで言語固有にすることができますGetMessage。このようにして、リソースからプロパティ名に基づいてカルチャに依存するテキストをフェッチできます。ただし、問題は、使用するすべての検証属性に対してサブクラスを作成する必要があり、検証属性ごとに、サポートするバリデータークラスを継承する必要があることです。これは、属性ごとおよびバリデーターごとにそれほど多くのコードになるべきではありませんが、そのようなコードベースを維持することは依然として非常に苦痛です。

リソースにユーザーフレンドリーな言語固有の名前を含む完全なメッセージを単純に定義する方が簡単だと思います。


アップデート2:

私はおそらく役立つかもしれない何かを考えました。アプリケーションが一度に1つの言語のみを表示できる必要がある場合は、回避策がある可能性があります。表示されるメッセージがスレッドの現在のカルチャに基づいてローカライズされている場合、これは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
        }
    }
}

そのインスタンスをに提供するMyConfigurationSourceValidationFactory、より適切な統合が必要な場合は、このタイプをVAB構成に接続します。

ただし、コードで検証ルールを構築することは現在多くの作業であることに注意してください。特に、VABには(まだ)適切な流暢な構成APIがないためです(これについてはここで不満を述べています)。私はそれをはるかに簡単にするAPIを書いているところです(それについては私のブログに注目してください)。

幸運を。

于 2010-08-27T12:56:05.043 に答える