2012-02-24 10 views
2

理由:私のコントローラーの1つでは、アプリケーションの残りの部分とは異なる方法ですべてのDecimal値をバインドします。私はDefaultModelBinderクラスから派生する、私が試してみましたネストされたプロパティ値をバインドするカスタムモデルバインダー

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());経由)のGlobal.asaxでのモデルバインダーを登録し、そのBindPropertyメソッドをオーバーライドする必要はありませんが、それは唯一のモデルインスタンスの即時(ネストしていない)小数点の性質のために働きます。

私は私の問題を示すために、次の例があります。

namespace ModelBinderTest.Controllers 
{ 
    public class Model 
    { 
     public decimal Decimal { get; set; } 
     public DecimalContainer DecimalContainer { get; set; } 
    } 

    public class DecimalContainer 
    { 
     public decimal DecimalNested { get; set; } 
    } 

    public class DecimalModelBinder : DefaultModelBinder 
    { 
     protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor) 
     { 
      if (propertyDescriptor.PropertyType == typeof (decimal)) 
      {     
       propertyDescriptor.SetValue(bindingContext.Model, 999M); 
       return; 
      } 

      base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 
     } 
    } 

    public class TestController : Controller 
    { 

     public ActionResult Index() 
     { 
      Model model = new Model(); 
      return View(model); 
     } 

     [HttpPost] 
     public ActionResult Index([ModelBinder(typeof(DecimalModelBinder))] Model model) 
     { 
      return View(model); 
     } 

    } 
} 

このソリューションは、唯一の「999へのDecimalプロパティが、DecimalContainerに何もしない」Modelを設定し、S DecimalNestedプロパティ。これは、base.BindPropertyDecimalModelBinderBindPropertyオーバーライドで呼び出されたためですが、小数点プロパティを扱う際に、モデルクラスを使用するように基本クラスを説得する方法がわかりません。 HttpContextにいくつかの値を注入します、その後

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

と(それがモデルバインダーの前に実行されるようはい、許可フィルタ)カスタム認証フィルタを持っていた:

答えて

1

あなたのApplication_Startに無条件モデルバインダーを適用することができそれは後にモデルバインダーで使用することができます

[AttributeUsage(AttributeTargets.Method)] 
public class MyDecimalBinderAttribute : ActionFilterAttribute, IAuthorizationFilter 
{ 
    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     filterContext.HttpContext.Items["_apply_decimal_binder_"] = true; 
    } 
} 

、その後のHttpContextはそれを適用するbefoireカスタム値が含まれている場合、あなたのモデルバインダーのテストで:

[HttpPost] 
[MyDecimalBinder] 
public ActionResult Index(Model model) 
{ 
    return View(model); 
} 
:10
public class DecimalModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (controllerContext.HttpContext.Items.Contains("_apply_decimal_binder_")) 
     { 
      // The controller action was decorated with the [MyDecimalBinder] 
      // so we can proceed 
      return 999M; 
     } 

     // fallback to the default binder 
     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

は今残っているすべては、小数点バインダーを有効にするには、カスタムフィルタを使用してコントローラのアクションを飾るためにあります

関連する問題