5

に渡す前に、モデル値を操作しますつまり、パーセント記号や中間スペースなどを使用する場合と使用しない場合の両方で、データを入力する際の柔軟性をユーザーに許可するのが好きです。しかし、のチェックなど、すべての機能を利用するためにはDefaultModelBinderの動作を使用します。適切な検証メッセージ。は、私の見解モデルの一部の<code>decimal</code>と<code>decimal?</code>の特性は、例えば、他のデータ注釈とともに、「パーセント」データ型としてマークされているDefaultModelBinder.BindModel

を解析し、モデル値をに変更して、それを渡す方法はありますか?ここで私がしようとしているが、実行時例外を取得しています。 (実際の解析ロジックを無視してください。これは、その最終的な形ではありません、私はこの時点でモデルの交換問題のちょうど興味があります。。)

public class PercentModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, 
            ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelMetadata.DataTypeName == "Percent") 
     { 
      ValueProviderResult result = 
       bindingContext.ValueProvider.GetValue(
        bindingContext.ModelName); 
      if (result != null) 
      { 
       string stringValue = 
        (string)result.ConvertTo(typeof(string)); 
       decimal decimalValue; 
       if (!string.IsNullOrWhiteSpace(stringValue) && 
        decimal.TryParse(
         stringValue.TrimEnd(new char[] { '%', ' ' }), 
         out decimalValue)) 
       { 
        decimalValue /= 100.0m; 

        // EXCEPTION : This property setter is obsolete, 
        // because its value is derived from 
        // ModelMetadata.Model now. 
        bindingContext.Model = decimalValue; 
       } 
      } 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

答えて

5

を気にしない、これは検証がで起こるところの根本的な誤解でしたMVCサイクル。 MVCソースコードで時間を費やした後、私はこれがどのように動作するかを見ています。

それはここでは、他の人に助けになる場合は私のために働いているものです。

[DataType("Percent")] 
[Display(Name = "Percent of foo completed")] 
[Range(0.0d, 1.0d, ErrorMessage="The field {0} must be between {1:P0} and {2:P0}.")] 
public decimal? FooPercent { get; set; } 

とバインダーで、あなただけの値を返す:私にとって

public class PercentModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, 
            ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelMetadata.DataTypeName == "Percent") 
     { 
      ValueProviderResult result = 
       bindingContext.ValueProvider.GetValue(
        bindingContext.ModelName); 
      if (result != null) 
      { 
       string stringValue = 
        (string)result.ConvertTo(typeof(string)); 
       decimal decimalValue; 
       if (!string.IsNullOrWhiteSpace(stringValue) && 
        decimal.TryParse(
         stringValue.TrimEnd(new char[] { '%', ' ' }), 
         out decimalValue)) 
       { 
        return decimalValue/100.0m; 
       } 
      } 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 
+0

をカスタムバインダーがあります決して実行されません。あなたがやっていることはほかにありますか? –

関連する問題