JSON.stringify causing problems with decimal values in MVC Action parameters
PROBLEM
You may have noticed some time your MVC web site behave crazy when you are passing decimal values to a action. This decimal problem arises if you are using "JSON.stringify" to get JSON string to send with HTTP POST to a MVC controller action.
What causing the issue is JSON.stringify will behave as follows.
15.123 => 15.123
15.00 => 15
EX : {a:15.123, b:15.00} => "{a:15.123, b:15}"
When this json string reach MVC default model binder, it will convert 15.123 parameter as a decimal and 15 into a integer or long according to your value.
SOLUTION
1) Convert your decimal values to string before you pass it to JSON.stringify
2) Use a custom model binder for decimals (more info here : posted by Josh)
using System;
using System.Globalization;
using System.Web.Mvc;
public class DecimalModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
CultureInfo.CurrentCulture);
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
You may have noticed some time your MVC web site behave crazy when you are passing decimal values to a action. This decimal problem arises if you are using "JSON.stringify" to get JSON string to send with HTTP POST to a MVC controller action.
What causing the issue is JSON.stringify will behave as follows.
15.123 => 15.123
15.00 => 15
EX : {a:15.123, b:15.00} => "{a:15.123, b:15}"
When this json string reach MVC default model binder, it will convert 15.123 parameter as a decimal and 15 into a integer or long according to your value.
SOLUTION
1) Convert your decimal values to string before you pass it to JSON.stringify
2) Use a custom model binder for decimals (more info here : posted by Josh)
using System;
using System.Globalization;
using System.Web.Mvc;
public class DecimalModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
CultureInfo.CurrentCulture);
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
Comments
Post a Comment