Asp.net mvc 5 由于格式化,DateTime客户端验证失败

Asp.net mvc 5 由于格式化,DateTime客户端验证失败,asp.net-mvc-5,jquery-validate,fluentvalidation,Asp.net Mvc 5,Jquery Validate,Fluentvalidation,我在MVC5项目中使用FluentValidation,除了日期之外没有任何问题。我的目标是让GreaterThanOrEqualTo客户端验证为几个日期字段工作。我知道当前文档没有将此方法列为受支持的客户端,但它呈现了正确的jQuery验证数据属性 在我的模型中,我有一个属性: [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]

我在MVC5项目中使用FluentValidation,除了日期之外没有任何问题。我的目标是让
GreaterThanOrEqualTo
客户端验证为几个日期字段工作。我知道当前文档没有将此方法列为受支持的客户端,但它呈现了正确的jQuery验证数据属性

在我的模型中,我有一个属性:

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[Display(Name = "Credit Decision Due Date")]
public DateTime? DueDate { get; set; }
在我看来,我正在使用标准Razor语法来绘制控制组:

<div class="control-group">
    @Html.LabelFor(m => m.DueDate, new { @class = "control-label text-bold" })
    @Html.TextBoxFor(m => m.DueDate, "{0:MM/dd/yyyy}", new { @class = "span12 date-picker" })
    @Html.ValidationMessageFor(m => m.DueDate)
</div>
注意,我还尝试了
inclusivebeween
,(文档中明确列出了客户端支持):

使用
GreaterThanOrEqualTo
进行视图渲染的结果是:

<div class="control-group">
    <label class="control-label text-bold" for="DueDate">Credit Decision Due Date <span class="text-error required-asterisk">*</span></label>
    <input class="span12 date-picker hasDatepicker" data-val="true" data-val-range="'Credit Decision Due Date' must be greater than or equal to '9/27/2018 12:00:00 AM'." data-val-range-max="" data-val-range-min="09/27/2018 00:00:00" data-val-required="'Credit Decision Due Date' must not be empty." id="DueDate" name="DueDate" type="text" value="">
    <span class="field-validation-valid help-block" data-valmsg-for="DueDate" data-valmsg-replace="true"></span>
</div>
默认情况下,整个应用程序使用“en-US”语言环境。所有其他验证都在进行中

我正在使用以下库版本:

  • FluentValidation 8
  • jQuery 1.11.3
  • jQuery验证1.17
  • jQuery验证不引人注目的3.2.10(Microsoft)
我知道我可以编写一个自定义验证器,在比较之前将输入值和范围值解析为JavaScript
Date
对象,但似乎应该有内置的东西来让所有东西都能将这些字符串识别为日期


我缺少什么?

问题是
jquery.validate.js
中的
范围
规则使用数值,如果不是数值,则进行字符串比较

您可以通过添加自己的规则来比较日期,从而覆盖默认行为。在
validate*
脚本之后添加以下脚本,但不要在
$(文档)中添加。就绪

$.validator.methods.range = function(value, element, param) {
    if ($(element).attr('data-val-date')) {
        var min = $(element).attr('data-val-range-min');
        var max = $(element).attr('data-val-range-max');
        var date = new Date(value).getTime();
        var minDate = new Date(min).getTime() || 0;
        var maxDate = new Date(max).getTime() || 8640000000000000;
        return this.optional(element) || (date >= minDate && date <= maxDate);
    }
    // use the default method
    return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
};
还请注意,您的

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]

如果使用
TextBoxFor()
,则不需要属性-这些属性仅在使用
EditorFor()
时才受尊重,如果确实使用
EditorFor()
,则格式字符串应为ISO格式-即
DataFormatString=“{0:yyyy-MM-dd}”

中所述,问题在于
jquery.validate.js
中的
范围
规则使用数值,如果不是数值,则进行字符串比较

您可以通过添加自己的规则来比较日期,从而覆盖默认行为。在
validate*
脚本之后添加以下脚本,但不要在
$(文档)中添加。就绪

$.validator.methods.range = function(value, element, param) {
    if ($(element).attr('data-val-date')) {
        var min = $(element).attr('data-val-range-min');
        var max = $(element).attr('data-val-range-max');
        var date = new Date(value).getTime();
        var minDate = new Date(min).getTime() || 0;
        var maxDate = new Date(max).getTime() || 8640000000000000;
        return this.optional(element) || (date >= minDate && date <= maxDate);
    }
    // use the default method
    return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
};
还请注意,您的

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
如果使用
TextBoxFor()
,则不需要属性-这些属性仅在使用
EditorFor()
时才受尊重,如果确实使用
EditorFor()
,则格式字符串应为ISO格式-即
DataFormatString=“{0:yyyy-MM-dd}”
正如在

中所解释的那样,这是有效的——我没有深入探究为什么
data val nnnn
属性没有呈现(似乎是MVC或FluentValidation问题),而是在视图中手动添加了一个额外的
data\u val\u date=“true”
HTML属性。它同时适用于
.inclusiveBeween()
.GreaterThanOrEqualTo()
FluentValidation方法。这是有效的——在不深入探究
数据val nnnn
属性不呈现的原因(似乎是MVC或FluentValidation问题)的情况下,我手动添加了一个额外的
数据\u val\u date=“true”
my view中的HTML属性。它同时适用于
.inclusiveBeween()
.GreaterThanOrEqualTo()
流验证方法。
if ($(element).hasClass('date-picker')) {
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]