MVC验证 - 更新另一个字段?

时间:2016-07-26 15:09:32

标签: c# asp.net-mvc validation

我们目前正在创建几个输入字段,其中包含开始和结束日期时间,每个字段中有一个。我们目前正在进行验证,以便在用户将结束时间之后的开始时间(以及在开始之前的结束时间)放置时显示错误消息,但是我们遇到了一个有趣的问题。

例如,如果用户在开始时间之前设置了结束时间,我们会在结束时间收到预期的错误消息。

enter image description here

但是,如果修改开始日期而不是结束日期,则消息仍然存在。

enter image description here

有没有办法在不同的字段上删除/更新/更正验证消息?这是验证的代码:

[Required(ErrorMessage = "{0} is required!")]
[Display(Name = "Start Date")]
[Remote("IsTestPlanEndCorrect", "Analysis", AdditionalFields = "EndDate", HttpMethod = "Post", ErrorMessage = "Test Plan Start Time must be before End.")]
public System.DateTime StartDate { get; set; }

[Required(ErrorMessage = "{0} is required!")]
[Display(Name = "End Date")]
[Remote("IsTestPlanEndCorrect", "Analysis", AdditionalFields = "StartDate", HttpMethod = "Post", ErrorMessage = "Test Plan End Time must be after Start.")]
public System.DateTime EndDate { get; set; }

IsTestPlanEndCorrect只是一个返回true或false的方法,具体取决于传递的数据是否通过验证。

编辑: 字段的剃刀代码:

<div class="form-group">
@Html.LabelFor(t => t.StartDate, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
        @Html.TextBoxFor(t => t.StartDate, new { @class = "form-control datetimepicker", placeholder = "Enter Test Plan Start"})
        @Html.ValidationMessageFor(t => t.StartDate)
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(t => t.EndDate, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(t => t.EndDate, new { @class = "form-control datetimepicker", placeholder = "Enter Test Plan End"})
        @Html.ValidationMessageFor(t => t.EndDate)
    </div>
</div>

控制器中的验证码:

[HttpPost]
public JsonResult IsTestPlanEndCorrect(DateTime EndDate, DateTime StartDate )
{
    return Json(TimeManipulation.checkDate(StartDate,EndDate));
}

2 个答案:

答案 0 :(得分:1)

行为的原因是为您编辑的元素触发了jquery客户端验证(最初在.blur()上,然后在.keyup()上)。更改StartDate文本框中的值不会触发EndDate值的验证,它只会触发StartDate值的验证,因此验证消息不会消失。

您可以通过专门触发“其他”文本框中的.keyup()事件来解决此问题,例如

$('#StartDate').change(function() {
    $('#EndDate').trigger('keyup'); // or $('#EndDate').valid();
});
$('#EndDate').change(function() {
    $('#StartDate').trigger('keyup'); // or $('#StartDate').valid();
});

但是,使用RemoteAttribute检查客户端中已知的值是浪费资源,每次更改值时,您至少会对数据库进行2次调用。此外,远程验证仅在客户端进行,您需要在POST方法中再次重复验证逻辑,并手动添加ModelStateError以防止恶意用户。

相反,使用实现IClientValidatable的自定义验证属性,以便在不需要ajax调用的情况下获得客户端和服务器端验证。有关实施自己的指南,请参阅The Complete Guide To Validation In ASP.NET MVC 3 - Part 2。或者对于现成的解决方案,请考虑使用foolproof [GreaterThan][LessThan]验证属性。请注意,通常您将一个或另一个应用于其中一个属性,但如果您确实要将它应用于两者,例如

[LessThan("EndDate")]
public DateTime StartDate { get; set; }
[GreaterThan("StartDate")]
public DateTime EndDate { get; set; }

然后您仍然需要触发上面提到的.keyup()事件,以使其他消息消失。

答案 1 :(得分:0)

您可能希望/需要使用Table invoices (`id`,`user_id`,`zname` etc) Table invoices_product (`invoice_id`,`unixstamp`,etc) 实现此目的:

jQuery

每当 发生更改时,这将导致为 两个 字段调用验证领域。您可能希望在此代码中添加一些额外的检查,例如,如果结束日期为空,您可能不想检查它。