MVC3模型绑定的原因“从类型‘System.Int32’到‘System.Decimal’的参数转换失败 - 没有类型转换器”

问题描述:

,我发现了以下异常:MVC3模型绑定的原因“从类型‘System.Int32’到‘System.Decimal’的参数转换失败 - 没有类型转换器”

异常{“参数转换 从类型“System.Int32”键入 “System.Decimal”失败,因为没有 型转换器可以在这些类型之间转换 “} System.Exception的 {} System.InvalidOperationException

这是我后使用JQuer y Ajax帖子将json发回控制器。 MVC3正确地将JSON绑定到模型,因为我可以看到手表中的所有数据,但是ModelState存在此错误。

视图有一个单独的小数字段和一个包含数字的文本框。 即使文本框具有整数值,我也会收到此错误。

任何想法为什么这是失败?

这个问题似乎源于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

要稍微改善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());