2013-07-17 2 views
6

MVC4에서 작업 중이며 Uppercase 속성을 사용하여 모델을 정의하려고합니다. 아이디어는 Uppercase 속성의 존재로 인해 모델 값이 서버에 도착했을 때 대문자로 변환됩니다. 나는 모델 내에서 다음 코드가 순간 입력을 대문자로 변환하는 대문자 속성

:

[Required] 
    [Display(Name="Account Code")] 
    [StringValidation(RegExValidation.AccountCode, Uppercase=true)] 
    public string Account 
    { 
     get { return _account; } 
     set 
     { 
      if (value != null) 
       _account = value.ToUpper(); 
     } 
    } 

하지만 제가 정말 좋아하는 것은 이것이다 :

[Required] 
    [Display(Name="Account Code")] 
    [StringValidation(RegExValidation.AccountCode)] 
    [Uppercase] 
    public string Account { get; set; } 

나는 내가 대문자 속성을 만들어야 할 수도 있다고 생각 모델이 서버에 도달 할 때 해당 모델이 실행되도록하려면 ValidationAttribute으로 지정하십시오. 하지만 실제로는 데이터의 유효성을 검사하지 않기 때문에 약간 잘못되었습니다. 더 좋은 방법이 있습니까?

또한 속성에 대한 호출 순서를 보장 할 수있는 방법이 있습니까? 사용자 정의 StringValidation 속성이 실행되기 전에 데이터를 대문자로 변환하려고합니다. 정규 표현식 패턴의 텍스트 대/소문자를 검사합니다.

배경을 약간 추가하려면 코드를 추가하여 데이터를 대문자로 만들 필요가 없습니다. 너바나는 모델 바인딩 또는 유효성 검사 단계에서 서버로가는 도중에 데이터를 업데이트하는 단일 속성입니다. 이 특성은 StringValidation 특성에서 참조되어 해당 검사에 사용 된 RegEx 값을 수정합니다. 또한 사용자 지정 TextBoxFor 도우미 메서드에서이 특성을 조회 할 수 있으므로 text-transform: uppercase을 추가하여 클라이언트 측에서 올바르게 표시되도록 할 수 있습니다.

아무도 아이디어가 있습니까?

답변

5

나는이 점을 보완 해 냈다. 그래서 다른 사람들이 평가할 수있는 나의 해결책이있다.

StringValidation.IsValid() 속성 내에 Modelmetadata을 가져올 수 없기 때문에 전체 솔루션을 얻을 수 없다는 점에 유의하십시오. 여기에있는 특정 문제는 메타 데이터를 얻을 수 있다는 것이지만 PropertyNameDisplayName에서 가져올 수 없었습니다. 거기에 여러 옵션이 있지만 사실 내 재산 중 일부는 동일 DisplayName 의미는 내가 ProprtyName 내가 실제로 유효 확인했다 것을 확신 할 수 없다는 것을 의미합니다.

public class StringValidationAttribute : ValidationAttribute, IClientValidatable, IMetadataAware { 

    private bool _uppercase; 

    public StringValidationAttribute(bool uppercase = false) { 
     _uppercase = uppercase; 
    } 

    ... 

    public void OnMetadataCreated(ModelMetadata metadata) 
    { 
     metadata.AdditionalValues["Uppercase"] = _uppercase; 
    } 
} 

내가 다음 새 IModelBinder 구현 만든 : 여기

ValidationAttribute에 대한 코드의

public class StringBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    {   
     ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

     if (result == null) 
      return null; 

     if (bindingContext.ModelMetadata.AdditionalValues.ContainsKey("Uppercase")) { 
      if ((bool)bindingContext.ModelMetadata.AdditionalValues["Uppercase"]]) 
       return result.AttemptedValue.ToUpper(); 
     } 

     return result.AttemptedValue; 
    } 
} 

을 등록 나의 Global.asax 파일 :

ModelBinders.Binders.Add(typeof(string), new StringBinder()); 

코드 지금까지 모든 문자열 입력 co 모델에 StringValidationAttribute이 붙어 있고 대문자 표시기가 설정된 경우 MVC로 이동하여 대문자로 변환합니다. html로 양식을 만드는 내 욕망을 달성하기

다음, 나는 string.cshtml라는 새 EditorTemplate을 구현, 너무 대문자. 이보기에서 나는 덧붙였다과 CSS와

RouteValueDictionary htmlAttributes = new RouteValueDictionary(); 
if ((bool)ViewData.ModelMetadata.AdditionalValues["Uppercase"]) { 
    htmlAttributes.Add("class", "Uppercase"); 
} 
@Html.TextBox("", Model, htmlAttributes) 

을;

.Uppercase { 
    text-transform: uppercase; 
} 

희망이 게시물이 일부 다른 사람을 도움이됩니다.

+0

정말 멋지다! –

+0

안녕하세요, MVC 4에 적용됩니까? 다음과 같은 오류가 표시됩니다. 'UpperCaseValidationAttribute'는 'System.Web.Mvc.IClientValidatable.GetClientValidationRules (System.Web.Mvc.ModelMetadata, System.Web.Mvc.ControllerContext)'인터페이스 멤버를 구현하지 않습니다. 감사!! – ecasper

+0

예 MVC4에서 작동합니다. 당신은'public IEnumerable GetClientValidationRules (ModelMetadata 메타 데이터, ControllerContext 컨텍스트)에 대한 오버라이드를 추가해야합니다. 이것은 약간의 ... 답변 : – Nick

0

맞아요, ValidationAttribute이 적합하지 않습니다. Model Binding 단계에서이 작업을 수행하는 것이 더 좋은 아이디어 일 것 같습니다. 이 동작을 사용자 지정하는 방법에 대한 자세한 설명은 this article을 참조하십시오. 가 제공 한 정보를 바탕으로

, 나는이 같은 CustomModelBinderAttribute에 따라 속성을 만들 수있을 것으로 판단 :이 테스트하지 않았습니다

[AttributeUsage(AttributeTargets.Property)] 
public class UppercaseAttribute : CustomModelBinderAttribute 
{ 
    public override IModelBinder GetBinder() 
    { 
     return new UppercaseModelBinder(); 
    } 

    private class UppercaseModelBinder : DefaultModelBinder 
    { 
     public override object BindModel(
      ControllerContext controllerContext, 
      ModelBindingContext bindingContext) 
     { 
      var value = base.BindModel(controllerContext, bindingContext); 
      var strValue = value as string; 
      if (strValue == null) 
       return value; 
      return strValue.ToUpperInvariant(); 
     } 
    } 
} 

. 작동하는지 여부를 알려주세요.

+0

감사합니다. Daniel, 불행히도 DefaultModelBinder는 속성에 할당 할 수 없습니다. 'AttributeUsageAttribute (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Parameter' – Nick

+0

그러면 우리는 한 단계 더 높아야 할 것입니다.이러한 문자열이 포함 된 클래스의 모델 바인더를 변경하고 UppercaseAttribute를 단순 표시 속성으로 변경하고 모델 바인더에게이 속성을 찾아 해당 문자열을 다르게 처리하도록 알려야합니다. –

-1

참고 : 내가 지금 사용하는 방법을 발견 할 때까지, 나는 이것을 읽고 실패보다도 노력 때문에 나는이 게시물에 추가 해요 .

일반적으로 텍스트 데이터 강제 대문자로 처리 할 때 두 부분 프로세스를 사용합니다. 사용자 데이터가 대문자 형태로 사용될 예정 인식 할 수 있도록한다는 관점에서 계층 제어기

  1. 의 관점에서 (1)과 (2). 이것은 EditorFor HTML 도우미에서 사용되는 htmlAttributes를 통해 사용할 수 있습니다.

    @HTML.EditorFor(model => model.Access_Code, new { htmlAttributes = new Style= "text-transform:uppercase"}}) 
    

지금이 사용자 만 볼과 입력 한 데이터가 서버로 전송되는 데이터를 대문자가 아닌 강제로. 이를 수행하려면 컨트롤러의 관련 메소드에 일부 코드가 필요합니다.

  1. Contoller로 다시 전달되는 개체의 대상 특성에 ToUpper() 메서드를 추가합니다. 여기에 이것을 보여주는 가상의 예가 있습니다.

    public ActionResult verify(int? id) 
         { 
         var userData = db.user.Where (i=> i.userID == id).Single(); 
    
         userData.Access_Code = userData.Access_Code.ToUpper(); 
    
        ... 
    } 
    
0

웹 API의 목적은 대문자 또는 소문자로 입력 JSON 변환하는 것이 좋습니다.

public class ToUpperCase : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      return objectType == typeof(string); 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      return reader.Value.ToString().ToUpper(); 
     }    
    } 



    [Display(Name = "PNR NAME")] 
    [JsonConverter(typeof(Annotations.ToUpperCase))] 
    public string PNR { get; set; } 

또는 전 세계적으로;

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     //.......... others 



     JsonMediaTypeFormatter jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter; 
     JsonSerializerSettings jSettings = new Newtonsoft.Json.JsonSerializerSettings(); 
     jSettings.Converters.Add(new UpperCaseStringConverter()); 
     jsonFormatter.SerializerSettings = jSettings; 
    } 
관련 문제