2011-11-30 5 views
6

Problema:ASP.NET MVC4 localizzazione convalida discreto

ho problemi di ottenere i messaggi predefiniti per essere localizzati per implicito [Required] attributi utilizzando la convalida jQuery discreto. Non voglio mettere [Richiesto] su ogni int (e altri tipi non annullabili) nel mio modello e nel file di risorse associato. Mi chiedo se qualcuno ha testato ASP Preview di ASP.NET MVC4 e notato lo stesso problema? Quando guardo il codice mvc, sembra che dovrebbe funzionare.

soluzione Tentativo:

Aggiunto nel global.asax:

DefaultModelBinder.ResourceClassKey = "ErrorMessages"; 

Avere un file di risorse chiamato "ErrorMessages.resx" e "ErrorMessages.fr.resx" nelle risorse globali con PropertyValueInvalid e PropertyValueRequired.

Informazioni interessanti:

Una buona cosa che ho notato è che hanno fissato il "campo deve essere un numero" o "Il campo deve essere una data" di essere codificato duro in una classe di tenuta interna.

ClientDataTypeModelValidatorProvider.ResourceClassKey = "ErrorMessages"; 

funziona se si dispone di un file di risorse chiamato "ErrorMessages.resx" e "ErrorMessages.fr.resx" nei ressources globali cartella e FieldMustBeNumeric/FieldMustBeDate

+2

Stai dicendo che ha funzionato in MVC2/3 e si è rotto nell'anteprima v4? – RickAndMSFT

risposta

2

So che questo è vecchio, ma per ottenere i messaggi localizzati nei metadati è creare sottoclassi DataAnnotationsModelValidator e sovrascrivere GetClientValidationRules e Validate per fornire i propri messaggi.

Si registra l'adattatore utilizzando DataAnnotationsModelValidatorProvider.RegisterAdapterFactory.

Ho creato un costruttore di wrapper factory per creare il delegato di fabbrica. Il parametro out è qui mentre lo uso all'interno di un loop mentre scopro tutti gli adattatori nell'assembly tramite reflection, quindi ho bisogno di ottenere il tipo di attributo per ogni adattatore per chiamare RegisterAdpaterFactory. Avrei potuto inline la registrazione ma ho altre cose dopo questo utilizzando l'adattatore/informazioni sugli attributi

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; 
    } 
} 

Questo funziona anche in MVC3, e penso MVC2 pure.