2010-01-18 3 views
3

사용자에게 표시 될 값을 수정하는 ASP.NET MVC 용 모델 바인더를 작성하고 싶습니다. 어쩌면 값의 첫 글자, 줄 바꿈 등을 대문자로 쓸 것입니다.ModelBinder를 사용하여 사용자가 볼 수있는 값을 수정하려면 어떻게해야합니까?

이 동작을 모델 바인더 내에 캡슐화하고 싶습니다.

예를 들어 문자열을 자르려면 TrimModelBinder입니다. (taken from here)

public class TrimModelBinder : DefaultModelBinder 
    { 
    protected override void SetProperty(ControllerContext controllerContext, 
     ModelBindingContext bindingContext, 
     System.ComponentModel.PropertyDescriptor propertyDescriptor, object value) 
    { 
     if (propertyDescriptor.PropertyType == typeof(string)) 
     { 
     var stringValue = (string)value; 
     if (!string.IsNullOrEmpty(stringValue)) 
      stringValue = stringValue.Trim(); 

     value = stringValue; 
     } 

     base.SetProperty(controllerContext, bindingContext, 
          propertyDescriptor, value); 
    } 
    } 

이 모델에 값을 설정하지만 페이지가 다시 표시 될 때 (그들은 ModelState에이기 때문에) 원래 값이 유지됩니다.

트림 된 값을 사용자에게 다시 표시하고 싶습니다.

는 오버라이드 (override)하는 방법의 전체를 많이 Theres는 - OnPropertyValidated처럼, 그리고 OnPropertyValidating

나는 아마 일을 얻을 수 있지만 잘못된 메소드를 오버라이드 (override)하는 경우 내가 어떤 의도하지 않은 부작용을 가지고 싶지 않아 .

내가보기를 생성 할 때 Trim() 또는 논리가 무엇이든 시도하지 않으려합니다. 나는이 논리를 모델 바인더 안에 완전히 캡슐화하고 싶다.

답변

0

모델 바인더 내에서 ModelBindingContext에 액세스 할 수 있습니다. 이 경우 ModelState에 액세스 할 수 있으며 해당 사전의 값을 잘라내어 수정할 수 있어야합니다.

아마 같은 :

string trimmedValue = GetTheTrimmedValueSomehow(); 
modelBindingContext.ModelState[modelBindingContext.ModelName] = trimmedValue; 
+0

하는 이벤트에 대한 내가이 작업을 수행해야하는지에 대한 어떤 생각을 (원래는 계층 적 모델을 지원하기 위해 null 참조 예외 및 추가 변경을했다) 또는 어떻게 ModelState.Value의 'AttemptedValue'및 'RawValue'속성을 처리해야합니까? –

+0

모델 바인더 자체에서이 작업을하는 것이 좋습니다. 문자열 값의 경우 AttemptedValue와 RawValue는 동일합니다. 저는 AttemptedValue가 배열 값의 쉼표로 구분 된 목록을 포함하는 문자열과 같이 RawValue의 문자열 표현 인 반면 RawValue는 개별 값의 실제 배열이라고 생각합니다. – Eilon

+0

ya 나는 그들이 더 나은 이름을 갖기를 바랍니다. StringRepresentation과 ParsedValue 또는 이와 비슷한 것입니다. –

2

이 클래스를 교체합니다.

public class TrimModelBinder : DefaultModelBinder 
    { 
    protected override void SetProperty(ControllerContext controllerContext, 
     ModelBindingContext bindingContext, 
     System.ComponentModel.PropertyDescriptor propertyDescriptor, object value) 
    { 
     if (propertyDescriptor.PropertyType == typeof(string)) 
     { 
     var stringValue = (string)value; 
     if (!string.IsNullOrEmpty(stringValue)) 
      stringValue = stringValue.Trim(); 

     value = stringValue; 
     bindingContext.ModelState[propertyDescriptor.Name].Value = 
      new ValueProviderResult(stringValue, 
      stringValue, 
      bindingContext.ModelState[propertyDescriptor.Name].Value.Culture); 
     } 

     base.SetProperty(controllerContext, bindingContext, 
       propertyDescriptor, value); 
    } 
    } 

편집 : 사이먼에 의해 수정은

protected override void SetProperty(ControllerContext controllerContext, 
    ModelBindingContext bindingContext, 
    System.ComponentModel.PropertyDescriptor propertyDescriptor, 
    object value) 
    { 
     string modelStateName = string.IsNullOrEmpty(bindingContext.ModelName) ? propertyDescriptor.Name : 
      bindingContext.ModelName + "." + propertyDescriptor.Name; 

     // only process strings 
     if (propertyDescriptor.PropertyType == typeof(string)) 
     { 
      if (bindingContext.ModelState[modelStateName] != null) 
      { 
       // modelstate already exists so overwrite it with our trimmed value 
       var stringValue = (string)value; 
       if (!string.IsNullOrEmpty(stringValue)) 
        stringValue = stringValue.Trim(); 

       value = stringValue; 
       bindingContext.ModelState[modelStateName].Value = 
        new ValueProviderResult(stringValue, 
        stringValue, 
        bindingContext.ModelState[modelStateName].Value.Culture); 
      } 
      else 
      { 
       // trim and pass to default model binder 
       base.SetProperty(controllerContext, bindingContext, propertyDescriptor, (value == null) ? null : (value as string).Trim()); 
      } 
     } 
     else 
     { 
      base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value); 
     } 
    } 
+0

에 대해 올바른 유형이 아닙니다. 몇 가지 문제가 있습니다. - 끝에 추가했습니다. 내 변경 사항 및 포인트를 부여 –

+0

변경 코드, 사이먼 주셔서 감사! – takepara

관련 문제