MVC / JQueryvalidation不接受逗号作为小数分隔符

更新07.01.2018

即使有人提出,这是一个jQuery问题而不是MVC问题,我认为这是一个MVC问题。 我已经在asp.net core 2.0 MVC中创建了整个应用程序并且错误仍然存​​在。 将它与MVC联系起来的是,我可以通过将[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]到模型中来解决日期validation问题。 因此,MVC对validation有影响。 所以我认为在MVC中有一些方法可以解决这个问题(参见这篇文章 )。 请发布asp.net core 2.0的答案。

原帖

在MVC5页面中,我在文本框中渲染一个Double属性。 加载页面时,该值显示为“,”作为小数分隔符,这是正确的,因为页面在德语系统上运行。 如果我想保存表单,我会收到validation错误。 怎么解决这个问题? 我知道关于这个话题有一些问题,但据我所知,其中大部分已经过时了…我仍然在苦苦挣扎,没有任何设置或任何内置的东西允许来自不同国家的用户使用MVC应用程序。

模型:

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

CSHTML:

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

Web.config文件

  

加载后的框 – >用逗号作为小数分隔符加载的值 在此处输入图像描述

单击提交按钮后的框 – >相同值的validation错误

在此处输入图像描述

逗号后的框更改为点 – >无validation错误 在此处输入图像描述

更新05.01.2018

我试过这里显示的解决方案,遗憾的是这对我不起作用。 但是,我还发现,这些值不仅不会被接受,而且还会变为组分隔符和小数分隔符混合的数字(见图片)。 会发生的是,22的值变为22.5并存储在数据库中。 结果是,将值2,250.00存储到数据库中。

在此处输入图像描述

更新07.01.2018

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

属性

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

接受并处理下面显示的值没有任何错误。 在此处输入图像描述

更新07.01.2018 – 2

如果我更改edit.cshtml中的行

  

  

表单可以使用值“23,7”提交,不会出现validation错误。 在控制器中,绑定模型属性显示值“237”,其中IFormCollection显示值“23.7”。 这表明模型绑定器存在问题。

即使有人提出,这是一个jQuery问题而不是MVC问题,我认为这是一个MVC问题。

不,这是不正确的。 您看到客户端validation错误,因为默认情况下, jquery.validate.js (与MicroSoft无关的独立第三方插件,MVC用于客户端validation)根据小数分隔符为avalidation数字. (点),而不是, (逗号)。

MVC是服务器端代码,不在浏览器中运行。 为了执行客户端validation,生成表单控件的MVC的HtmlHelper方法在html中呈现一组data-val-*属性,用于描述要执行的validation,这些属性又由jquery.validate.unobtrusive.js插件解析加载DOM时,使用它们将规则添加到$.validator

double属性的情况下,它将添加data-val-number属性(除了data-val-required属性),这将添加定义为的number规则

 // 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); }, 

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

您需要覆盖使用jquery.globalize等插件或包含以下脚本可以执行的默认行为(请注意正则表达式只是交换点和逗号)

 $.validator.methods.number = function (value, element) { return 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}")]到模型中来解决日期validation问题。

实际上你的[DataType(DataType.Date)]属性与影响生成的html的[DisplayFormat]属性一起使用。 [DataType]属性生成 ,如果浏览器支持,则会将浏览器HTML-5 datepicker呈现给它。 根据规范,格式必须是yyyy-MM-dd (ISO格式),因此也需要[DisplayFormat]属性。

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

客户端validation对date属性起作用的原因是jquery.validate.js插件包含US格式( MM/dd/yyyy )和ISO格式( yyyy-MM-dd )的日期规则。

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

我认为问题是jqueryvalidation器我用它来解决逗号/点错误

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

试试玩吧

更强大的解决方案可能是将validation器方法包装在您自己的函数中,该函数将逗号分隔的数字转换为小数分隔的数字。

一个技巧是使用.call调用原始的validation器函数,好像“this”是开发人员认为的原始函数(例如,他们使用函数“this.optional”进行步骤validation)。

 var originalNumber = $.validator.methods.number; var wrappedNumber = function (value, element) { var fixedValue = parseFloat(value.toString().replace(",", ".")); return originalNumber.call($.validator.prototype, fixedValue, element); // Call function as if "this" is the original caller }; $.validator.methods.number = wrappedNumber; 

您可以将此工作用于任何validation器,例如步骤validation:

 var originalStep = $.validator.methods.step; var wrappedStep = function (value, element, param) { var fixedValue = parseFloat(value.toString().replace(",", ".")); return originalStep.call($.validator.prototype, fixedValue, element, param); }; $.validator.methods.step = wrappedStep;