MVC/JQuery 验证不接受逗号作为小数点分隔符 [英] MVC/JQuery validation does not accept comma as decimal separator

查看:36
本文介绍了MVC/JQuery 验证不接受逗号作为小数点分隔符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2018 年 1 月 7 日更新

尽管有人建议说这是一个 jQuery 问题而不是 MS ASP MVC 问题,但我认为这是一个 MVC 问题.我已经在 asp.net core 2.0 MVC 中创建了整个应用程序,但错误仍然存​​在.对我来说,将它与 MVC 联系起来的是,我可以通过添加以下行来解决日期验证问题 [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")] 到模型.因此,MVC 对验证有影响.所以我认为 MVC 有一些方法可以解决这个问题(见这个

点击提交按钮后的框 --> 相同值的验证错误

逗号后的框改为点 --> 无验证错误

2018 年 1 月 5 日更新

我已经尝试了

2018 年 1 月 7 日更新

同样有趣的是,日期字段完全可以接受德语格式.

财产

私有日期时间?inbetriebnahmedatum;[数据类型(数据类型.日期)][DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]公共日期时间?水母{得到 { 返回 inbetriebnahmedatum;}设置 { inbetriebnahmedatum = 值;OnPropertyChanged(new PropertyChangedEventArgs("Inbetriebnahmedatum"));}}

下面显示的值被接受和处理,没有任何错误.

更新 07.01.2018 - 2

如果我将 edit.cshtml 中的行从

可以使用值23,7"提交表单而不会出现验证错误.在控制器中,绑定模型属性显示值237",而 IFormCollection 显示值23.7".这表明模型绑定器存在问题.

解决方案

尽管有人建议说这是一个 jQuery 问题而不是 MVC 问题,但我认为这是一个 MVC 问题.

不,那是不正确的.您看到客户端验证错误,因为默认情况下,jquery.validate.js(与 MicroSoft 无关的独立 3rd 方插件,MVC 用于客户端验证)基于小数分隔符验证数字是 .(点),而不是 ,(逗号).

MVC 是服务器端代码,不在浏览器中运行.为了执行客户端验证,MVC 的 HtmlHelper 方法生成表单控件在 html 中呈现一组 data-val-* 属性,用于描述要执行的验证,其中当 DOM 加载时,jquery.validate.unobtrusive.js 插件依次解析,并使用这些来向 $.validator 添加规则.

对于您的 double 属性,它将添加一个 data-val-number 属性(除了 data-val-required属性),这将添加定义为

number规则

//http://docs.jquery.com/Plugins/Validation/Methods/number数字:函数(值,元素){返回 this.optional(element) ||/^-?(?:d+|d{1,3}(?:,d{3})+)?(?:.d+)?$/.test(value);},

其中小数点分隔符是点,千位分隔符是逗号(大概是因为插件是在美国开发的,所以使用了美国格式).

您需要使用诸如 jquery.globalize 之类的插件来覆盖默认行为,或包括以下脚本(注意正则表达式只是交换点和逗号)

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

注意上面的脚本需要在 jquery.validate.js 脚本之后,而不是包裹在 $(document).ready()

<块引用>

对我来说,将它与 MVC 联系起来的是我可以通过添加行 [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}") 来解决日期验证问题] 到模型.

它实际上是您的 [DataType(DataType.Date)] 属性与 [DisplayFormat] 属性一起影响生成的 html.[DataType] 属性生成 <input type="date" .../> 如果浏览器支持它,它会反过来呈现浏览器 HTML-5 日期选择器.根据规范,格式必须是 yyyy-MM-dd(ISO 格式),因此也需要 [DisplayFormat] 属性.

HTML-5 日期选择器在浏览器文化中呈现日期.您在输入为 26.1.2018 的地方显示的图像是因为您的浏览器文化是 de-DE,但是如果我导航到您的网站,我会看到 26/1/2018 在输入中,因为我的文化是 en-AU(澳大利亚),如果美国用户导航到您的网站,他们会看到 1/26/2018.

客户端验证适用于 date 属性的原因是 jquery.validate.js 插件包含两种美国格式的日期规则 (MM/dd/yyyy)和 ISO 格式 (yyyy-MM-dd).

如果你使用 @Html.TextBoxFor(m => m.Inbetriebnahmedatum)(忽略你的 [DataType][DisplayFormat] 属性),并在输入中输入 26.1.2018,您还会看到客户端验证错误.

Update 07.01.2018

Even though it was suggested, that this is rather a jQuery problem than an MS ASP MVC problem, I think it is an MVC Problem. I've created the whole app in asp.net core 2.0 MVC and the error persist. What links it to MVC for me, is the fact that I can solve the date validation problem by adding the line [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")] to the model. Hence, MVC has an influence on the validation. So I would assume there is some way in MVC to fix this (See this post). Please post answers for asp.net core 2.0.

Original Post

In an MVC5 page I render a Double Property in a Textbox. When the page is loaded, the value is shown with a "," as decimal separator, which is correct, as the page runs on an German System. If I want to save the form, I get an validation error. How can this be solved? I know that there are some questions on the topic, but as far as i can see, most of them are outdated... I'm still struggling, that there is no setting or anything built-in that allows users from different countries to work with MVC apps.

Model:

[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public Double Gewicht
{
    get { return gewicht; }
    set { gewicht = value; OnPropertyChanged(new PropertyChangedEventArgs("Gewicht")); }
}

CSHTML:

<div class="form-group">
    @Html.LabelFor(model => model.Gewicht, htmlAttributes: new { @class = "control-label col-md-3" })
    <div class="col-md-8">
        @Html.EditorFor(model => model.Gewicht, new { htmlAttributes = new { @class = "form-control col-md-1" } })
        @Html.ValidationMessageFor(model => model.Gewicht, "", new { @class = "text-danger" })
    </div>
</div>

Web.config

<globalization uiCulture="de-DE" culture="de-DE" />

Box after its loaded --> Value loaded with a comma as decimal separator

Box after submit button is clicked --> Validation error for the same value

Box after comma is changed to point --> No validation error

Update 05.01.2018

I've tried the solution shown here which unfortunately doesn't work for me. However, I also discovered, that the values not only get not acceptet, but are also changed to numbers where group separator and decimal separator are mixed up (see picture). What happens is, that the value of 22 gets changed to 22.5 and stored in the database. The result beeing, that a value of 2,250.00 is stored to the database.

Update 07.01.2018

What is also interesting, is the fact that the date fields accept the german format perfectly fine.

Property

private DateTime? inbetriebnahmedatum;

[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? Inbetriebnahmedatum
{
    get { return inbetriebnahmedatum; }
    set { inbetriebnahmedatum = value; OnPropertyChanged(new PropertyChangedEventArgs("Inbetriebnahmedatum")); }
}

The value shown below is accepted and processed without any errors.

Update 07.01.2018 - 2

If I change the line in edit.cshtml from

<input asp-for="Gewicht" class="form-control" />

to

<input name="Gewicht" id="Gewicht" type="number" class="form-control" value="@Model.Gewicht"/>

The form can be submitted with the value "23,7" without validation errors. In the controller, the bound model property shows a value of "237", where as the IFormCollection shows a value of "23.7". This would suggest a problem with the model binder.

解决方案

Even though it was suggested, that this is rather a jQuery problem than an MVC problem, I think it is an MVC Problem.

No that is no correct. You seeing a client side validation error because, by default, jquery.validate.js (an independent 3rd party plugin not associated with MicroSoft, that MVC uses for client side validation) validates numbers based on the decimal separator being a . (dot), not a , (comma).

MVC is server side code and does not run in the browser. To perform client side validation, MVC's HtmlHelper methods that generate form controls render a set of data-val-* attributes in the html used to describe the validation to be performed, which are in turn parsed by the jquery.validate.unobtrusive.js plugin when the DOM is loaded, and uses those to add rules to the $.validator.

In the case of your double property it will add a data-val-number attribute (in addition to data-val-required attribute), which will add the number rule which is defined as

// http://docs.jquery.com/Plugins/Validation/Methods/number
number: function( value, element ) {
    return this.optional(element) || /^-?(?:d+|d{1,3}(?:,d{3})+)?(?:.d+)?$/.test(value);
},

where the decimal separator is a dot, and the thousands separator is a comma (presumably because the plugin was developed in the US, so uses a US format).

You need to overwrite the default behavior which you can do by using plugins such as jquery.globalize, or including the following script (note the regex just swaps the dot and comma)

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

Note the above script needs to be after the jquery.validate.js script but not wrapped in $(document).ready()

What links it to MVC for me, is the fact that I can solve the date validation problem by adding the line [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")] to the model.

Its actually your [DataType(DataType.Date)] attribute in conjunction with the [DisplayFormat] attribute that is influencing the html that is generated. The [DataType] attribute generates <input type="date" ... /> which in turn renders the browsers HTML-5 datepicker if the browser supports it. In accordance with the specifications the format must be yyyy-MM-dd (ISO format) hence the need for the [DisplayFormat] attribute as well.

The HTML-5 datepicker renders the date in the browsers culture. The image you have shown where the input is 26.1.2018 is because your browser culture is de-DE, but if I navigated to your site, I would see 26/1/2018 in the input because my culture is en-AU (Australian), and if a United States user navigated to your site, they would see 1/26/2018.

The reason client side validation works for the date property is that the jquery.validate.js plugin includes date rules for both US format (MM/dd/yyyy) and ISO format (yyyy-MM-dd).

And if you were to use @Html.TextBoxFor(m => m.Inbetriebnahmedatum) (which ignores your [DataType] and [DisplayFormat] attributes), and entered 26.1.2018 in the input, you would also see a client side validation error.

这篇关于MVC/JQuery 验证不接受逗号作为小数点分隔符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆