2011-11-30 4 views
6

문제 :ASP.NET MVC4 겸손한 검증 현지화

나는 기본 메시지를 받고 문제가 로컬 라이즈 할 필요가 암시 [필수] 눈에 거슬리지 JQuery와 유효성 검사를 사용하여 속성. 내 모델의 모든 int (및 null이 아닌 다른 유형) 및 연관된 ressource 파일에 [Required]를 넣고 싶지 않습니다. 누군가가 ASP.NET MVC4 개발자 미리보기를 테스트하고 동일한 문제를 발견했는지 궁금합니다. 내가 mvc 코드를 볼 때 명확하게 작동해야하는 것처럼 보입니다.

시도 해결책 : Global.asax에있는

추가 :

DefaultModelBinder.ResourceClassKey = "ErrorMessages"; 

글로벌 자원에 "ErrorMessages.resx"와 "ErrorMessages.fr.resx"라는 리소스 파일이 PropertyValueInvalid 및 PropertyValueRequired입니다.

재미있는 정보 :

내가 발견 한 좋은 것은 그들이 열심히 내부 봉인 클래스에 코딩되는 "필드가 날짜해야한다"는 "필드의 숫자 여야합니다"고정 또는 것입니다.

ClientDataTypeModelValidatorProvider.ResourceClassKey = "ErrorMessages"; 

는 글로벌 능숙에서 "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 생각 때문이다.