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);
}
}
答
要稍微改善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());
任何人都可以解释为什么默认行为简化版,虽然工作?我真的不明白为什么会这样。 – Dan 2011-05-12 19:40:40
不知道,我想过提出一个针对MVC3项目的bug,但最终我没有得到机会。 – jaffa 2011-05-23 10:31:55