2011-11-30 38 views
6

問題:ASP.NET MVC4不顯眼的驗證本地化

我有獲取默認的郵件問題進行本地化隱[必需]使用不顯眼的jQuery驗證屬性。我不希望在我的模型中的每個int(以及其他非空類型)上放置​​[Required],並關聯該資源文件。我想知道是否有人測試了ASP.NET MVC4 Dev Preview並注意到相同的問題?當我看到mvc代碼時,它顯然看起來應該起作用。

嘗試的解決方案:

添加在Global.asax:

DefaultModelBinder.ResourceClassKey = "ErrorMessages"; 

已在全球資源與所謂的 「ErrorMessages.resx」 和 「ErrorMessages.fr.resx」 資源文件PropertyValueInvalid和PropertyValueRequired。

有趣的信息:

我注意到一個很好的事情是,他們固定在「字段必須是一個數字」或「現場必須有個約會」從內部密封類被硬編碼。

ClientDataTypeModelValidatorProvider.ResourceClassKey = "ErrorMessages"; 

,如果你有在全球ressources稱爲「ErrorMessages.resx」和「ErrorMessages.fr.resx」資源文件夾是否工作,FieldMustBeNumeric/FieldMustBeDate

+2

你是說這在MVC2/3中工作,並在v4預覽中被打破? – RickAndMSFT

回答

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爲好。