mvc3 jquery unobtrusive validation locale decimal

2019-04-28 12:12发布

问题:

I'm working on localized mvc3 web application using unobtrusive validation. In web.config I've got :

<globalization culture="pl-PL" uiCulture="pl" />

Jquery 1.4.4 and jquery validation 1.6 is in use.

Problem is with decimal number separator character.

I can see that jquery validation is ignoring the culture and is expecting a dot character to always be the decimal separator. I need to use comma instead. I think it's the same in German language for example.

I created my own methods_pl.js file :

jQuery.extend(jQuery.validator.methods, {
number: function(value, element) {
    return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
}
});

Above is solving the basic problem where decimal number is not recognized at all.

But when I try to use RangeAttribute on my model Decimal Price property it still doesn't work. How to solve this?

回答1:

If you set

key="UnobtrusiveJavaScriptEnabled" value="false"

the DecimalModelBinder posted in the previous answer will work, but you are disabling the clien-side validations.

To solve your problem you need to inlcude the correct jQuery locale. Look a this post from Scott Hanselmann or this post they should give you some help in implementing it.

You should add the Jquery.globalize plugin form NuGet then in your DOMready function add something like that to have number validated correctly (at least it works for me)

 $.validator.methods.number = function (value, element) {
        if (Globalize.parseFloat(value)) 
            return true;
        return false;
    }
 Globalize.culture('fr-FR');

then add the relative scripts in your page

<script src="@Url.Content("~/Scripts/jquery-1.7.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/globalize.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/cultures/globalize.culture.fr-FR.js")" type="text/javascript"></script>


回答2:

Phil Haack posted some information about this issue.

See here.

In the post he desribes doing the following:

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;
    }
}

and then in Global.asax

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

I'm not sure if this resolves the problem on the client as well (Phil seems to indicate it will work), but it should resolve the issue on the server side at the least.