我遇到以下异常:
异常{“参数转换 从类型'System.Int32'到键入 'System.Decimal'失败,因为没有 类型转换器之间可以转换 这些类型。“} System.Exception {System.InvalidOperationException}
这是在我使用JQuery Ajax帖子将json发布回控制器之后。 MVC3正确地将JSON绑定到模型,因为我可以看到监视中的所有数据,但是ModelState有这个错误。
视图有一个十进制字段和一个包含数字的文本框。 即使文本框有整数值,我也会收到此错误。
关于为何失败的任何想法?
答案 0 :(得分:13)
问题似乎源于默认的Model Binder,它伴随着MVC3无法将整数转换为小数。但是,如果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);
}
}
答案 1 :(得分: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,无法提供合适的转换器。此时我停止了寻找:)
还记得处理Nullable小数:
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());