Search code examples
c#asp.net-mvcasp.net-mvc-3globalization

MVC3 globalization issue


I'm developing a MVC3 application with the next culture setup:

<globalization enableClientBasedCulture="true" uiCulture="auto" culture="auto"/>

First when I pass values from the view to the controller when I pass a integer all ok, but when I passed a double (3.2) the value in the controller was returned in 0 as was described in this question. Ok model binders added:

protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();

  ModelBinders.Binders.Add(typeof(double), new DoubleModelBinder());
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);

}
public class DoubleModelBinder : 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.ToDouble(valueResult.AttemptedValue,
                CultureInfo.InvariantCulture);
        }
        catch (FormatException e)
        {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

If I use like default the culture "en-US" it's all okay but when I try to setup globalization to auto (that's what I need) my culture is "es-ES" and when I write "3,2" don't detect me field as a number. The problem and the answer is described here: use the plug-in developed in jquery by microsoft and the model binder. The model binder don't fix my problem and the plug-in linked in the microsoft page don't work (broken link). What can I do?

Update:

I downloaded Globalize from nuget and added the lines according to this link (I don't know why stackoverflow don't allow me to copy that code)

That deactivates all the validations.


Solution

  • For server side you must use this model binder:

    public object BindModel(ControllerContext controllerContext, 
                              ModelBindingContext bindingContext)
            {
                var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                if (string.IsNullOrEmpty(valueResult.AttemptedValue))
                {
                    return 0m;
                }
                var modelState = new ModelState { Value = valueResult };
                object actualValue = null;
                try
                {
                    actualValue = Convert.ToDecimal(
                        valueResult.AttemptedValue.Replace(",", "."),
                        CultureInfo.InvariantCulture
                    );
                }
                catch (FormatException e)
                {
                    modelState.Errors.Add(e);
                }
    
                bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
                return actualValue;
            }
    

    And for client side take a look at this POST