6

問題:

目立たない jquery 検証を使用して、暗黙的な [Required] 属性のデフォルト メッセージをローカライズする際に問題があります。モデルと関連付けられたリソース ファイル内のすべての int (およびその他の null 非許容型) に [Required] を配置したくありません。ASP.NET MVC4 Dev Preview をテストして、同じ問題に気付いた人はいますか? mvc コードを見ると、明らかに動作するように見えます。

試みられた解決策:

global.asax に追加:

DefaultModelBinder.ResourceClassKey = "ErrorMessages";

PropertyValueInvalid と PropertyValueRequired を使用して、グローバル リソースに "ErrorMessages.resx" と "ErrorMessages.fr.resx" という名前のリソース ファイルを用意します。

興味深い情報:

私が気づいた良いことは、「フィールドは数値でなければならない」または「フィールドは日付でなければならない」が内部シールクラスでハードコーディングされないように修正したことです。

ClientDataTypeModelValidatorProvider.ResourceClassKey = "ErrorMessages"; 

グローバル リソース フォルダーに「ErrorMessages.resx」および「ErrorMessages.fr.resx」という名前のリソース ファイルがあり、FieldMustBeNumeric/FieldMustBeDate がある場合は機能します

4

1 に答える 1

2

これが古いことは承知していますが、ローカライズされたメッセージをメタデータに入れるには、DataAnnotationsModelValidator をサブクラス化し、GetClientValidationRules と Validate をオーバーライドして独自のメッセージを提供します。

DataAnnotationsModelValidatorProvider.RegisterAdapterFactory を使用してアダプターを登録します。

ファクトリー デリゲートを作成するためのラッパー ファクトリー ビルダーを作成しました。リフレクションを介してアセンブリ内のすべてのアダプターを検出するときにループ内でこれを使用するため、out パラメーターはここにあります。したがって、RegisterAdpaterFactory を呼び出すには、各アダプターの属性タイプを取得する必要があります。登録をインライン化することもできましたが、この後、アダプター/属性情報を使用して他のことを行います

public static class ModelValidationFactory
{
    /// <summary>
    /// Builds a Lamda expression with the Func&lt;ModelMetadata, ControllerContext, ValidationAttribute, ModelValidator&gt; signature
    /// to instantiate a strongly typed constructor.  This used by the <see cref="DataAnnotationsModelValidatorProvider.RegisterAdapterFactory"/>
    /// and used (ultimately) by <see cref="ModelValidatorProviderCollection.GetValidators"/> 
    /// </summary>
    /// <param name="adapterType">Adapter type, expecting subclass of <see cref="ValidatorResourceAdapterBase{TAttribute}"/> where T is one of the <see cref="ValidationAttribute"/> attributes</param>
    /// <param name="attrType">The <see cref="ValidationAttribute"/> generic argument for the adapter</param>
    /// <returns>The constructor invoker for the adapter. <see cref="DataAnnotationsModelValidationFactory"/></returns>
    public static DataAnnotationsModelValidationFactory BuildFactory(Type adapterType, out Type attrType)
    {
        attrType = adapterType.BaseType.GetGenericArguments()[0];

        ConstructorInfo ctor = adapterType.GetConstructor(new[] { typeof(ModelMetadata), typeof(ControllerContext), attrType });

        ParameterInfo[] paramsInfo = ctor.GetParameters();

        ParameterExpression modelMetadataParam = Expression.Parameter(typeof(ModelMetadata), "metadata");
        ParameterExpression contextParam = Expression.Parameter(typeof(ControllerContext), "context");
        ParameterExpression attributeParam = Expression.Parameter(typeof(ValidationAttribute), "attribute");

        Expression[] ctorCallArgs = new Expression[]
        {
            modelMetadataParam,
            contextParam,
            Expression.TypeAs( attributeParam, attrType )
        };

        NewExpression ctorInvoker = Expression.New(ctor, ctorCallArgs);

        // ( ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute ) => new {AdapterType}(metadata, context, ({AttrType})attribute)
        return Expression
            .Lambda(typeof(DataAnnotationsModelValidationFactory), ctorInvoker, modelMetadataParam, contextParam, attributeParam)
            .Compile()
            as DataAnnotationsModelValidationFactory;
    }
}

これはMVC3でも機能し、MVC2も同様だと思います。

于 2012-09-25T03:52:23.940 に答える