如何使用3个输入字段验证日期?

时间:2016-06-05 02:23:32

标签: c# asp.net-mvc validation date asp.net-mvc-5

我有3个输入字段:年,月和日。我想验证输入的日期是否有效。例如,如果有人输入“2016-02-31”,则应返回错误。

我的问题是我不能为DateTime使用1个输入字段,因为最终用户需要输入很多日期,并且有3个输入,他输入的速度要快得多,因为他可以更快地使用键盘上的TAB键导航到下一个输入字段。

如果有人有更好的解决方案,我会很高兴听到它。

编辑:我需要客户端和服务器端验证。

2 个答案:

答案 0 :(得分:1)

首先,您需要从视图模型开始,以表示您的日期

public class DateVM
{
    public DateVM() { } // default constructor required by the DefaultModelBinder
    public DateVM(DateTime date) // useful if your editing existing dates
    {
        Date date.Date;
        Day = date.Day;
        Month = date.Month;
        Year = date.Year;
    }
    public int Day { get; set; }
    public int Month { get; set; }
    public int Year { get; set; }
    [Required(ErrorMessage = "The values for the date are not valid")]
    public DateTime Date { get; set; }
}

然后主视图模型将包含public List<DateVM> Dates {get; set; }属性。

虽然可以创建一个实现ValidationAttribute的自定义IClientValidatable,(请参阅The Complete Guide to Validation-in-ASP.NET-MVC-3 Part-2以获得实施一个的好指南),但它会出现一些设计问题,例如哪个属性你将属性应用于?,当其他属性之一未被编辑时会发生什么?等

相反,我建议您只包含自己的脚本来处理每个控件的.change()事件并验证日期(并在适当时显示错误消息),并处理表单.submit()事件如果无效,取消帖子。

您编辑日期的部分视图需要

for(int i = 0; i < Model.Dates.Count; i++)
{
    <div class="date-container">
        @Html.LabelFor(m => m.Dates[i].Year)
        @Html.TextBoxFor(m => m.Dates[i].Year, new { @class = "year" })
        @Html.ValidationMessageFor(m => m.Dates[i].Year)
        @Html.LabelFor(m => m.Dates[i].Month)
        @Html.TextBoxFor(m => m.Dates[i].Month, new { @class = "month" })
        @Html.ValidationMessageFor(m => m.Dates[i].Month)
        @Html.LabelFor(m => m.Dates[i].Day)
        @Html.TextBoxFor(m => m.Dates[i].Day, new { @class = "day" })
        @Html.ValidationMessageFor(m => m.Dates[i].Day)
        @Html.HiddenFor(m => m.Dates[i].Date, new { @class = "date" })
        @Html.ValidationMessageFor(m => m.Dates[i].Date, null, new { @class = "validation" })
    </div>
}

然后包含以下脚本

$('.day, .month, .year').change(function () {
    var container = $(this).closest('.date-container');
    var day = Number(container.find('.day').val());
    var month = Number(container.find('.month').val());
    var year = Number(container.find('.year').val());
    if (isNaN(day) || isNaN(month) || isNaN(year) || day === 0 || month === 0 || year === 0) {
        container.find('.date').val('');
        return;
    }
    var date = new Date(year, month - 1, day);
    var isValid = date.getDate() === day && date.getMonth() === month - 1 && date.getFullYear() === year;
    if (isValid) {
        container.find('.date').val(year + '-' + month + '-' + day);
        container.find('.validation').text('').addClass('field-validation-valid').removeClass('field-validation-error');
    } else {
        container.find('.date').val('');
        container.find('.validation').text('The values for the date are not valid').addClass('field-validation-error').removeClass('field-validation-valid');
    }
});

$('form').submit(function () {
    $.each($('.date'), function () {
        if (!$(this).val()) {
            return false;
        }
    });
})

答案 1 :(得分:0)

据我所知,你必须创建自己的自定义验证器。

在Google上查看有关ValidationAttributeIClientValidatable和 - 在您的情况下 - 还有IValidatableObject的更多信息。

几个例子:

另见this question


其他方式 - 您可以考虑使用三个字段的日期选择器控制瞬间。日期选择器为您提供了简单的日期验证方法以及一些有趣的功能。

试试这个:eternicode/bootstrap-datepicker(也可通过凉亭获得)。