2011-03-16 1 views
2

을 수행하는 방법은 숫자를 처리 할 때 더 현명하게 바인딩 기본 모델을 확장하고자합니다. 쉼표와 소수점이 게임에서 가리킬 때 기본값은 매우 나쁩니다. 사용자 정의 모델 바인더 : MVC 전에 문자열 값을 얻을 똑똑한 전환이

는 내가 새로운 바인더

Public Class SmartModelBinder 
    Inherits DefaultModelBinder 
    Protected Overrides Sub SetProperty(controllerContext As ControllerContext, bindingContext As ModelBindingContext, propertyDescriptor As System.ComponentModel.PropertyDescriptor, value As Object) 
     If propertyDescriptor.PropertyType Is GetType(Decimal) Or propertyDescriptor.PropertyType Is GetType(Decimal?) Then 
      If value Is Nothing Then 
       value = 0 
      End If 
     End If 

     MyBase.SetProperty(controllerContext, bindingContext, propertyDescriptor, value) 
    End Sub 
End Class 

을 시도하고 있었다 그러나 값은 이미

가 어떻게 양식에서 문자열 값을 가져오고을 수행하기 위해 바인더를 확장 할 수있는이 시점에서 변환된다 다른 변형?

+0

방금 ​​어떻게 든 세계화를 활성화 할 수 있습니다

여기에 자신의 게시물에 대한 링크가있어? http://haacked.com/archive/2010/05/10/globalizing-mvc-validation.aspx – Ryan

+1

네,하지만 그건 질문이 아닙니다. 쉼표로 정수를 분리하면 기본 모델 바인더에 오류가 발생합니다. 여기서 사람들은 때때로 쉼표를 사용하고 때로는 점을 소수 구분 기호로 사용합니다. 나는 바인딩에 적용하고 싶은 많은 트릭을 가지고있다. –

답변

4

어떨까요?

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder()) 

맞춤 바인더. 이 방법으로 10 진수 바인딩을 재정의 할 수 있는지 모르겠지만 내 자신의 형식에 대해 작동합니다.

public class DecimalModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     if (valueProviderResult == null) 
     { 
      return base.BindModel(controllerContext, bindingContext); 
     } 
     // to-do: your parsing (get the text value from valueProviderResult.AttemptedValue) 
     return parsedDecimal; 
    } 
} 
+0

그게 다야! 감사! (답변에 조금 더 많은 정보가 추가되었습니다) –

+3

필 하크 (Phil Haack)가 이제이 정확한 문제에 관한 글을 올렸습니다. http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx – Ryan

+0

예. 그것을 보았고 나의 작은 말을 덧붙여 라. –

2

아마도 찾고있는 방법은 BindModel입니다. 여기에 기본 모델 바인더 작동 방법에 대한 높은 수준의 개요는, 당신은 다음과 같은 클래스가 있다고 가정

public class MyModel 
{ 
    public int Id; 
    public string Name; 
} 

MVC는 MyModel에 데이터를 바인딩 할 시도, 그것은 기본 모델 바인더에 BindModel 호출합니다. 즉, 결합제는 MyModel는 "단순"데이터 타입이 아님을 판정한다 (즉 int, decimal, string 등). 그런 다음 바인드 할 수있는 가능한 멤버를 추출한 다음 해당 유형별로 올바른 모델 바인더를 찾고 해당 모델/바인더의 BindModel 메소드를 호출하여 필드/특성에 대해 메소드를 호출하므로 복잡한 유형의 모델 바인딩은 실제로 재귀 호출입니다.

일반적으로 그냥 소수의 모델 바인더를 작성하고 모델 데이터 유형에 대한 바인더, 그러나 나는 다른 사람이 그와 문제가 있었다 들었어요 (나는 그것을 자신을 시도하지 않은) 것으로 설정하는 것이 좋습니다 것입니다. 그래서 먼저 시도해 볼 것이고, 작동하지 않는다면 기본 모델 바인더의 BindModel 메서드에서 해당 모델 유형을 확인하고 그 특별한 경우를 처리하십시오.

이 바인딩 모델의 매우 높은 수준의 개요이며, 심지어 당신이 그 지역이 어떻게 작동하는지에 대해 알아야 할 모든의 제안을 시작하지 않을 것입니다. 필 Haack이 작업을 수행하는 방법을 정확하게에 최근 블로그 때문에

+0

시간 내 주셔서 감사합니다! –

1

제가 추가 답변을 추가 해요. 그는 테스트되지 않았다고 경고하지만 그는 ModelState을 사용하고 필요하다면 오류를 추가합니다. 이는 내가 언제/어떻게해야하는지 전혀 알지 못했기 때문에 나에게 도움이되었습니다. http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx