本文介绍了问题与小数,逗号和客户端验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现客户端验证一个可空<十进制> 的小数点分隔符可以是逗号(例如:123,45)。

I'm trying to achieve client-side validation for a nullable<decimal> whose decimal separator can be a comma (e.g.: 123,45).

在我的观点:

...

<div class="editor-label">
    @Html.LabelFor(model => model.Turnover)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Turnover)
    @Html.ValidationMessageFor(model => model.Turnover)
</div>

...

@section Scripts {

   @Styles.Render("~/Content/themes/base/css")
   @Scripts.Render("~/bundles/jquery")
   @Scripts.Render("~/bundles/jqueryui")
   @Scripts.Render("~/bundles/jqueryval")
   @Scripts.Render("~/bundles/jQueryFixes")
   ...scripts for this view...
}

我jQueryFixes覆盖 jquery.validate.js 文件的范围()号()

$.validator.methods.range = function (value, element, param) {
    var globalizedValue = value.replace(",", ".");
    return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}

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

...的建议中对这一问题(如许多岗位/问题:或)。

奇怪的是:

当我尝试提交这样的值,123,45,即使我已经调试与Firebug的剧本,看到我压倒函数被调用和返回true,我不能够提交表单。相反,我对十进制值EditorFor正集中无论出于何种原因,似乎我无法找出原因。

When I try to submit a value such as 123,45, and even though I've debugged the script with Firebug and seen that my overrode functions are being called and returning true, I'm not being able to submit the form. Instead, my EditorFor for the decimal value is being focused for whatever reason and I can't seem to find out why.

(我相信我的服务器端验证 - 使用自定义的粘结剂等 - 工作正常,并且在这里不是问题:我想就如何获取表单一些帮助提交或为什么输入字段越来越集中,即使它看起来有效。)

(I believe that my server-side validation - using a custom binder, etc. - is working fine and that is not the issue here: I would like some help on how to get the form to submit or why is the input field getting focused even though it looks valid.)

编辑1:

附加信息。在我的BundlesConfig.cs:

Additional info. In my BundlesConfig.cs:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));
...
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                    "~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));
bundles.Add(new ScriptBundle("~/bundles/jQueryFixes").Include(
                    "~/Scripts/jQueryFixes.js"));
...

编辑2:

@LeftyX的建议后,我尝试使用脚本全球化时代(删除我的jQueryFixes.js后):

After @LeftyX suggestion, I tried using the Globalize script (after removing my jQueryFixes.js):

<script type="text/javascript">
    ...

    $( document ).ready(function() {
        Globalize.culture("en-US", "pt-PT");
    });

    $.validator.methods.number = function (value, element) {
        return this.optional(element) || jQuery.isNumeric(Globalize.parseFloat(value));
    }

    //Fix the range to use globalized methods
    jQuery.extend(jQuery.validator.methods, {
        range: function (value, element, param) {
            var val = Globalize.parseFloat(value);
            return this.optional(element) || (val >= param[0] && val <= param[1]);
        }
    });

   ...
</script>

...但我仍然面临着同样的问题: validator.methods.number 将返回true,但形式不提交,输入字段被关注,而不是

...but I still face the same issue: the validator.methods.number is returning true but the form isn't submitted and the input field gets focused instead.

如果我检查输入的元素,而我提出的,我可以看到它迅速从进入类=有效类='输入-validation错误然后再返回到有效。很奇怪的。

If I inspect the input element while I submit, I can see that it quickly goes from class="valid" to class='input-validation-error' and then back to valid. Very strange.

结论:

@LeftyX给了谁发现了同样的问题一个很好的和完整的解决方案。

@LeftyX gave a very good and complete solution for whoever finds the same issues.

我已经拥有可空小数的自定义模型绑定,但全球化的脚本,并在模型中包括文化/视图模型肯定就派上用场了。

I already had a custom model binder for the nullable decimals, but the globalization script and including the culture in the Model/ViewModel sure comes in handy.

另一个原因,我的问题可能包括两次一些脚本的事实,我是(不小心)。

Another reason for my problem could be the fact that I was (accidentally) including some scripts twice.

UPDATE(月/ 2015):

现在是一个有点不同。参考。到this回答和。

globalize.js is a bit different now. Ref. to this answer and the documentation for the updated steps.

推荐答案

我挣扎着相当多与此有关。

I've struggled quite a bit with this.

对我来说,最好的方法是定义一个小数定制绑定:

The best approach for me is to define a custom binder for decimals:

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
        {
            //Check if this is a nullable decimal and a null or empty string has been passed
            var isNullableAndNull = (bindingContext.ModelMetadata.IsNullableValueType &&
                                     string.IsNullOrEmpty(valueResult.AttemptedValue));

            //If not nullable and null then we should try and parse the decimal
            if (!isNullableAndNull)
            {
                actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
            }
        }
        catch (FormatException e)
        {
            modelState.Errors.Add(e);
        }

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

和在其绑定在的Application_Start 的Global.asax

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

我也用在全球化脚本(与文化),它可以在这里找到 工作的例子.

An extended explanation can be found here.

关于在全球化脚本和文化的一些更多的信息设置。

Some more info about the globalize script and culture settings here.

这篇关于问题与小数,逗号和客户端验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 23:06