MVC/JQuery 验证不接受逗号作为小数分隔符
Posted
技术标签:
【中文标题】MVC/JQuery 验证不接受逗号作为小数分隔符【英文标题】:MVC/JQuery validation does not accept comma as decimal separator 【发布时间】:2018-01-02 18:49:20 【问题描述】:更新 07.01.2018
尽管有人建议这是一个 jQuery 问题而不是 MS ASP MVC 问题,但我认为这是一个 MVC 问题。我已经在 asp.net core 2.0 MVC 中创建了整个应用程序并且错误仍然存在。对我来说,将它与 MVC 联系起来的事实是,我可以通过在模型中添加行 [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0:yyyy-MM-dd")]
来解决日期验证问题。因此,MVC 对验证有影响。所以我认为 MVC 中有一些方法可以解决这个问题(参见post)。请发布 asp.net core 2.0 的答案。
原帖
在 MVC5 页面中,我在文本框中呈现 Double
属性。加载页面时,该值显示为“,”作为小数分隔符,这是正确的,因为该页面在德语系统上运行。如果我想保存表单,我会收到验证错误。如何解决?我知道关于这个话题有一些问题,但据我所知,它们中的大多数都已经过时了......我仍然在苦苦挣扎,没有任何设置或内置任何东西可以让来自不同国家的用户使用 MVC 应用程序。
型号:
[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" />
加载后的框 --> 以逗号作为小数分隔符加载的值
单击提交按钮后的框 --> 相同值的验证错误
逗号后的方框改为点-->没有验证错误
更新 05.01.2018
我已经尝试了here 所示的解决方案,但不幸的是它对我不起作用。但是,我还发现,这些值不仅不被接受,而且还更改为混合了组分隔符和小数分隔符的数字(见图)。发生的情况是,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 中的行<input asp-for="Gewicht" class="form-control" />
到
<input name="Gewicht" id="Gewicht" type="number" class="form-control" value="@Model.Gewicht"/>
可以使用值“23,7”提交表单而不会出现验证错误。在控制器中,绑定模型属性显示的值为“237”,而IFormCollection
显示的值为“23.7”。这表明模型绑定器存在问题。
【问题讨论】:
我不认为这是相似的,因为我使用[DisplayFormat(DataFormatString = "0:n2", ApplyFormatInEditMode = true)]
并且我对格式很好。我也希望有一种更“内置”的方法来解决这个问题,因为我无法想象 MVC 5 不允许以美国-美国以外的其他格式保存十进制值。
@Mister832 与 MVC5 无关。您看到的错误是由 jquery validate javascript 库产生的。您可以定义一个自定义验证器来处理逗号
谢谢,我更新了标题。我只是觉得它与基类中的数据注释有关。
如果您没有正确设置您的文化,也许可以使用您自己的模型粘合剂? ***.com/questions/793459/…
您可能对this plugin 感兴趣,它根据服务器文化显示和验证数字类型的输入
【参考方案1】:
尽管有人建议这是一个 jQuery 问题而不是 MVC 问题,但我认为这是一个 MVC 问题。
不,这是不正确的。您会看到客户端验证错误,因为默认情况下,jquery.validate.js
(与 MicroSoft 无关的独立 3rd 方插件,MVC 用于客户端验证)根据小数分隔符 .
(点)验证数字,不是,
(逗号)。
MVC 是服务器端代码,不在浏览器中运行。为了执行客户端验证,生成表单控件的 MVC 的 HtmlHelper
方法在 html 中呈现一组 data-val-*
属性,用于描述要执行的验证,当 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+|\d1,3(?:,\d3)+)?(?:\.\d+)?$/.test(value);
,
其中小数分隔符是点,千位分隔符是逗号(估计是因为插件是在美国开发的,所以使用美国格式)。
您需要覆盖默认行为,您可以通过使用 jquery.globalize 等插件或包含以下脚本来执行此操作(注意正则表达式只是交换点和逗号)
$.validator.methods.number = function (value, element)
return this.optional(element) || /^-?(?:\d+|\d1,3(?:\.\d3)+)?(?:,\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
,您还会看到客户端验证错误。
【讨论】:
【参考方案2】:我认为问题在于 jquery 验证器 我用它来解决逗号/点错误
$.validator.methods.number = function (value, element)
return this.optional(element) || /^-?(?:\d+|\d1,3(?:[\s\.,]\d3)+)(?:[\.,]\d+)?$/.test(value);
试试看吧
【讨论】:
谢谢,但如前所述,其目的是使用具有开箱即用功能的整个东西。尽管这个“oneliner”看起来很酷,但当我仍然不得不摆弄这样的事情时,MVC 应用程序的意义何在?特别是,当您观看 MVA 视频时,他们会称赞“仅模型”方法使 Web 界面设计变得如此简单......【参考方案3】:更强大的解决方案可能是将验证器方法包装在您自己的函数中,该函数将逗号分隔的数字转换为小数分隔的数字。
一个技巧是使用 .call 调用原始验证器函数,就好像“this”是开发人员认为的原始 this(例如,他们使用函数“this.optional”进行步骤验证)。
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;
您可以为任何验证器使用此功能,例如步骤验证:
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;
【讨论】:
喜欢这个解决方案,但重要的是要指出parseFloat
不足以进行数字转换,例如parseFloat("50-ba")
返回5
感谢您的评论。与编程中的几乎任何事情一样,答案是“视情况而定”。我们采用了一种不同的方法,为 模拟 但对于丹麦语言环境,通过将输入限制为 0-9 和一个带有 js 的 "," 字符.以上是关于MVC/JQuery 验证不接受逗号作为小数分隔符的主要内容,如果未能解决你的问题,请参考以下文章