MVC3自定义格式化日期的不显眼日期验证

时间:2011-11-09 00:46:47

标签: asp.net-mvc asp.net-mvc-3 jquery-validate datepicker unobtrusive-validation

我有一个日期字段(我正在使用jquery ui datepicker),我已经格式化了这样的形式,如下所示:

视图模型

[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime FooDate { get; set; }

查看

@Html.EditorFor(m => m.FooDate)

这正确地显示了我想要的日期,例如09-Nov-2011

当我按提交时,我会遇到问题。它一直告诉我日期无效....这是有效的,你这个蠢事!

有什么办法,我可以使用jquery / unobtrusive javascript来忽略这个字段或允许这种格式通过吗?到目前为止,我可以让表单工作的唯一方法是,如果我不格式化日期,或使用{0:d}作为日期格式。

修改: 我已经创建了一个完全独立的布局+视图+控制器+模型来测试这个愚蠢的东西。仍然无法在IE / Safari中运行。 我有来自nuget的最新jquery.validate / unobtrusive文件。

我的layout为空。它只加载以下文件:

"jquery-1.7.min.js"
"jquery-ui-1.8.16.min.js"
"jquery.validate.min.js"
"jquery.validate.unobtrusive.min.js"

我的TestViewModel很简单:

public class TestViewModel
{
    [Display(Name = "Test Date:")]
    [DisplayFormat(DataFormatString = "{0:dd/MMM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? TestDate { get; set; }
}

我的TestController如下:

public class TestController : Controller
{
    public ActionResult Index()
    {
        var m = new TestViewModel();
        m.TestDate = DateTime.Now;
        return View(m);
    }
}

我的观点:

@using (Html.BeginForm())
{
    ViewContext.FormContext.ValidationSummaryId = "valSumId";
    @Html.ValidationSummary(false, "The following errors were found:");
    @Html.AntiForgeryToken()

    @Html.LabelFor(m => m.TestDate)
    <input type="date" id="TestDate" value="@Model.TestDate.Value.ToString("dd/MMM/yyyy")" />
    <input type="submit" />
}

没有用。

你知道烦人的是什么吗?如果我将TestDate更改为字符串,它仍然会失败。

10 个答案:

答案 0 :(得分:4)

我认为格式字符串中的连字符(“ - ”)存在问题:

[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]

默认情况下,不显眼的验证似乎不接受连字符进行日期格式化。

在我的情况下,我不得不添加自定义客户端方法:

$.validator.methods.date = function (value, element) {
    var s = value;
    s = value.replace(/\-/g, '/');

    return this.optional(element) || !/Invalid|NaN/.test(new Date(s));
};

已实施here

答案 1 :(得分:3)

所以看起来 jquery.validate.unobtrusive input type="date"有问题。这必须是仅在IE和Safari中出现的错误。

当我删除不显眼的js文件时,它提交了表单。当我重新添加不显眼的js文件并将输入类型更改为文本时,它可以工作。

烦人的bug。需要修复。

答案 2 :(得分:2)

这里有两件事:

  1. 客户端验证
  2. 服务器端验证
  3. 两者都应该使用相同的格式来实现。让我们首先处理服务器端验证。您可以为DateTime字段编写自定义模型绑定器,这些绑定器将使用指定的格式进行绑定时显示。这是一个example of such model binder

    接下来我们必须处理客户端验证。为此,您可以编写一个自定义规则,该规则将附加到给定元素:

    <script type="text/javascript">
        $.validator.addMethod(
            'myDateFormat', function (value, element) {
                // TODO: put your validation logic here that will parse the string
                // and validate it
                return false;
            },
            'Please enter a date in the format dd-MMM-yyyy'
        );
    
        $(function () {
            // we attach the custom validation rule to the given input element
            $('#FooDate').rules('add', 'myDateFormat');
        });
    </script>
    

    您也可以使用adapters with a custom attribute

答案 3 :(得分:1)

对于我的情况,我使用文本字段作为日期,因此它没有导致jquery验证的问题:

 <div class="editor-field">
    @Html.TextBox("ExpiryDate", String.Format("{0:ddd, dd MMM yyyy}", DateTime.Now), new { id = "expirydate" })
    @Html.ValidationMessageFor(model => model.ExpiryDate)
</div>

那么为什么不尝试这样设置日期,而不是使用输入type = date?

希望这有帮助:)

答案 4 :(得分:1)

实际上它不是浏览器中的错误,因为 jquery.validate.unobtrusive.min.js 中的MVC错误(即使在MVC 5中)可能会发生客户端验证问题不接受以任何方式的日期/日期时间格式。不幸的是你必须手动解决它。

我的最终解决方案:

您必须先包括:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

您可以使用以下方式安装moment.js:

Install-Package Moment.js

然后你最终可以为日期格式解析器添加修复程序:

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});

答案 5 :(得分:1)

正如lukyer发布的那样,可能存在与 jquery.validate * .min.js 文件相关的问题,特别是如果您已将自己的验证添加到这些文件中。我发现,当最终发布系统无法验证IE中的日期(Chrome工作没有问题)时,我发现这个简单的答案就是简单地删除预先打包的缩小验证文件并让野兽处理它自己的缩小来自&#34;大师&#34;文件。唯一遗憾的是,我之前没有将lukyer的回复连接到解决方案......

(我可能会将此作为评论发布,但显然我还没有获得足够的代表:必须更加努力!)

答案 6 :(得分:0)

您是否尝试过将类型更改为:

@Html.TextBoxFor(model => model.startDate, new { @class = "date" })

我在编辑器中遇到了同样的问题...所以我把它改成了这个,然后将我的jquery datepicker应用到添加到文本框的'date'类。

答案 7 :(得分:0)

如果其他人稍后遇到问题,只想对这一行做一点评论:

<input type="date" id="TestDate" value="@Model.TestDate.Value.ToString("dd/MMM/yyyy")" />

在某些情况下(至少在我之前的情况下),这将转换为这种格式:“01.01.2012”,因为在某些文化中你无法指定像这样的斜线实际上将它格式化为那样,它只会转向他们变成了点,所以我不得不写:

@Model.TestDate.Value.ToString("dd\/MMM\/yyyy");

这给了我“01/01/2012”。

答案 8 :(得分:0)

相当老的这个帖子。刚刚降落在这里有类似的问题。在另一个帖子中,我读到,在验证过程中,所有这些* .js库都存在与版本不兼容的问题。 也许以下链接可以帮助其他读者登陆: https://stackoverflow.com/a/16551039

希望这有帮助

答案 9 :(得分:-1)

我遇到了同样的问题,它让我开车香蕉!基本上,mvc验证将始终使DateTime对象需要文本框上的值。为什么?因为它与DateTime对象直接关联。如果您声明ViewModel有?符号,你会让它可以为空。通过这种方式,您无需担心需要验证:

public class MyViewModel
{
    DateTime? StartDate { get; set; }
}

希望这有帮助

相关问题