2011-03-31 96 views
9

,我發現了以下異常:MVC3模型綁定的原因「從類型‘System.Int32’到‘System.Decimal’的參數轉換失敗 - 沒有類型轉換器」

異常{「參數轉換 從類型「System.Int32」鍵入 「System.Decimal」失敗,因爲沒有 型轉換器可以在這些類型之間轉換 「} System.Exception的 {} System.InvalidOperationException

這是我後使用JQuer y Ajax帖子將json發回控制器。 MVC3正確地將JSON綁定到模型,因爲我可以看到手錶中的所有數據,但是ModelState存在此錯誤。

視圖有一個單獨的小數字段和一個包含數字的文本框。 即使文本框具有整數值,我也會收到此錯誤。

任何想法爲什麼這是失敗?

回答

13

這個問題似乎源於MVC3自帶的默認Model Binder無法將整數轉換爲小數。但是,它可以轉換json中的源值是字符串還是十進制值。

解決方案是爲十進制值創建自定義模型聯編程序。

它添加到的global.asax.cs

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

,並創建模型綁定:

public class DecimalModelBinder : DefaultModelBinder 
    { 
     public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
     { 
      var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
      return valueProviderResult == null ? base.BindModel(controllerContext, bindingContext) : Convert.ToDecimal(valueProviderResult.AttemptedValue); 
     } 
    } 
+0

任何人都可以解釋爲什麼默認行爲簡化版,雖然工作?我真的不明白爲什麼會這樣。 – Dan 2011-05-12 19:40:40

+0

不知道,我想過提出一個針對MVC3項目的bug,但最終我沒有得到機會。 – jaffa 2011-05-23 10:31:55

10

要稍微改善Jaffa的偉大的答案,你可能需要使用Decimal.TryParse使不可轉換的值(如空字符串)不會拋出異常,而是交給基礎活頁夾以一致的方式進行處理。

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

     decimal value; 
     return valueProviderResult == null || !Decimal.TryParse(valueProviderResult.AttemptedValue, out value) ? base.BindModel(controllerContext, bindingContext) : value; 

    } 

據我所看到的,原故障是的ValueProviderResult不設置轉換器,其在內部來源於TypeDescriptor不能提供合適的轉換器。在這一點上我停止尋找:)

還記得來處理可空小數還有:

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder()); 
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder()); 
相關問題