C# MVC 模型验证时间
C# MVC Model Validation Timing
我们有一个模型,该模型以带有模型验证的局部视图的形式显示。我们有几个这样的字段:
[Required(ErrorMessage = "{0} cannot be empty")]
public string FirstName { get; set; }
[Required(ErrorMessage = "{0} cannot be empty")]
public string LastName { get; set; }
[RegularExpression(@"(\d{5})?", ErrorMessage = "Zip must be a 5 digit number or empty.")]
public string ZipCode { get; set; }
然后在视图中,我们为那些字段显示文本框,并为它们显示验证消息,如下所示:
<td>
@Html.TextBoxFor(m => m.Officer.FirstName)
@Html.ValidationMessageFor(m => m.Officer.FirstName)
</td>
<td>
@Html.TextBoxFor(m => m.Officer.LastName)
@Html.ValidationMessageFor(m => m.Officer.LastName)
</td>
<td>
@Html.TextBoxFor(m => m.Officer.ZipCode)
@Html.ValidationMessageFor(m => m.Officer.ZipCode)
</td>
验证工作正常,但我注意到时间有些奇怪,而且我找不到任何文档说明原因。
填写表格时,如果我将 FirstName 或 LastName 留空,则在我提交表格之前不会出现验证消息,检查模型状态是否有效并 return 到页面。
但是,如果我使用无效条目编辑邮政编码,验证消息会立即弹出,即使我没有提交表单也是如此。
有没有办法让它们同时处理,这样用户就不会觉得奇怪了?
ASP.NET MVC 使用数据注释进行服务器端和客户端验证。
在视图中,您正在使用 Razor.. 当您使用 HTML 辅助方法(例如 @Html.TextBoxFor
)呈现输入字段时,razor 视图引擎会查看应用于引用属性并将其他属性添加到 HTML 标记。
但是,只有 certain/standard 数据注释适用于客户端,它们是:
- [必需] - 如果您将其留空并且在点击提交之前,您将看不到验证消息。在单击 之后可以看到客户端性能 [=46] =] 并且表单没有被发送到服务器,因为客户端已经注意到这些字段是空的。您可以通过右键单击表单所在的页面并单击 'Inspect' 然后单击 'Network' 选项卡,然后点击提交(将所有必填字段留空)。您不应在该选项卡下看到任何内容,因为客户端在将表单发送到服务器之前验证了表单
- [字符串长度]
- [范围]
- [比较]
- [Phone]
- [电子邮件地址]
- [Url]
- [正则表达式]
此外,为了使其正常工作,在您的 Bundle.config.. 中您有一个可能称为 "~/bundles/jqueryval"
.. 的捆绑包,并且您的 _Layout
页面中未引用该捆绑包.但是,您的 _Layout
页面底部可能确实有一个名为 @RenderSection("scripts", required: false)
..
的部分
所以在你想要使用验证的视图底部,你需要写:
@section scripts{
@Scripts.Render("~/bundles/jqueryval")
}
如果不能实际使用表单很难说,但必须在消息出现之前触发客户端验证。提交表单当然是触发所有字段验证的蛮力方式,但除此之外,它基于表单字段状态。
jQuery Validation documentation详情:
By default, forms are validated on submit, triggered by the user clicking the submit button or pressing enter when a form input is focused (option onsubmit). In addition, once a field was highlighted as being invalid, it is validated whenever the user types something in the field (option onkeyup). When the user enters something invalid into a valid field, it is also validated when the field loses focus (option onblur). (emphasis mine)
关键是关于 "once a field was highlighted as being invalid" 的那一点。在验证字段之前,不会自动对其进行 运行 验证,除非字段中的值已更改或验证完整表单(例如提交时)。如果该字段最初为空而您将其保留为空,则从技术上讲它没有更改,因此没有验证状态。您可能会添加自己的触发器来验证模糊字段。例如:
$('#MyRequiredField').on('blur', function () {
$(this).valid();
});
但是,这违反了 jQuery 验证插件的惯例:
The goal of these interactions is to provide feedback as early as possible, whilst avoiding user annoyance. Displaying error messages before the user had the chance to even type something is not helpful.
请注意,用户可能会在表单中跳转是有充分理由的,仅仅因为用户尚未填写必填字段而显示错误消息并不总是合适的 .
更新
在我第一次通读您的问题时,我错过了在将这些字段留空时在再次返回视图之前实际返回操作的部分。我好像记得以前遇到过一个类似的问题,但是我不记得它是 MVC 版本特定的还是持久的。基本上,如果您使用 TextBoxFor
,则不会应用 "required" 客户端验证。您需要使用 EditorFor
或使用 @Html.TextBoxFor(m => m.Foo, new { required = true })
.
手动应用它
我认为您仍然会遇到如上所述最初未验证该字段的问题,但进行更改应确保它实际上被客户端验证捕获,而不是首先返回到服务器。
我们有一个模型,该模型以带有模型验证的局部视图的形式显示。我们有几个这样的字段:
[Required(ErrorMessage = "{0} cannot be empty")]
public string FirstName { get; set; }
[Required(ErrorMessage = "{0} cannot be empty")]
public string LastName { get; set; }
[RegularExpression(@"(\d{5})?", ErrorMessage = "Zip must be a 5 digit number or empty.")]
public string ZipCode { get; set; }
然后在视图中,我们为那些字段显示文本框,并为它们显示验证消息,如下所示:
<td>
@Html.TextBoxFor(m => m.Officer.FirstName)
@Html.ValidationMessageFor(m => m.Officer.FirstName)
</td>
<td>
@Html.TextBoxFor(m => m.Officer.LastName)
@Html.ValidationMessageFor(m => m.Officer.LastName)
</td>
<td>
@Html.TextBoxFor(m => m.Officer.ZipCode)
@Html.ValidationMessageFor(m => m.Officer.ZipCode)
</td>
验证工作正常,但我注意到时间有些奇怪,而且我找不到任何文档说明原因。
填写表格时,如果我将 FirstName 或 LastName 留空,则在我提交表格之前不会出现验证消息,检查模型状态是否有效并 return 到页面。
但是,如果我使用无效条目编辑邮政编码,验证消息会立即弹出,即使我没有提交表单也是如此。
有没有办法让它们同时处理,这样用户就不会觉得奇怪了?
ASP.NET MVC 使用数据注释进行服务器端和客户端验证。
在视图中,您正在使用 Razor.. 当您使用 HTML 辅助方法(例如 @Html.TextBoxFor
)呈现输入字段时,razor 视图引擎会查看应用于引用属性并将其他属性添加到 HTML 标记。
但是,只有 certain/standard 数据注释适用于客户端,它们是:
- [必需] - 如果您将其留空并且在点击提交之前,您将看不到验证消息。在单击 之后可以看到客户端性能 [=46] =] 并且表单没有被发送到服务器,因为客户端已经注意到这些字段是空的。您可以通过右键单击表单所在的页面并单击 'Inspect' 然后单击 'Network' 选项卡,然后点击提交(将所有必填字段留空)。您不应在该选项卡下看到任何内容,因为客户端在将表单发送到服务器之前验证了表单
- [字符串长度]
- [范围]
- [比较]
- [Phone]
- [电子邮件地址]
- [Url]
- [正则表达式]
此外,为了使其正常工作,在您的 Bundle.config.. 中您有一个可能称为 "~/bundles/jqueryval"
.. 的捆绑包,并且您的 _Layout
页面中未引用该捆绑包.但是,您的 _Layout
页面底部可能确实有一个名为 @RenderSection("scripts", required: false)
..
所以在你想要使用验证的视图底部,你需要写:
@section scripts{
@Scripts.Render("~/bundles/jqueryval")
}
如果不能实际使用表单很难说,但必须在消息出现之前触发客户端验证。提交表单当然是触发所有字段验证的蛮力方式,但除此之外,它基于表单字段状态。
jQuery Validation documentation详情:
By default, forms are validated on submit, triggered by the user clicking the submit button or pressing enter when a form input is focused (option onsubmit). In addition, once a field was highlighted as being invalid, it is validated whenever the user types something in the field (option onkeyup). When the user enters something invalid into a valid field, it is also validated when the field loses focus (option onblur). (emphasis mine)
关键是关于 "once a field was highlighted as being invalid" 的那一点。在验证字段之前,不会自动对其进行 运行 验证,除非字段中的值已更改或验证完整表单(例如提交时)。如果该字段最初为空而您将其保留为空,则从技术上讲它没有更改,因此没有验证状态。您可能会添加自己的触发器来验证模糊字段。例如:
$('#MyRequiredField').on('blur', function () {
$(this).valid();
});
但是,这违反了 jQuery 验证插件的惯例:
The goal of these interactions is to provide feedback as early as possible, whilst avoiding user annoyance. Displaying error messages before the user had the chance to even type something is not helpful.
请注意,用户可能会在表单中跳转是有充分理由的,仅仅因为用户尚未填写必填字段而显示错误消息并不总是合适的 .
更新
在我第一次通读您的问题时,我错过了在将这些字段留空时在再次返回视图之前实际返回操作的部分。我好像记得以前遇到过一个类似的问题,但是我不记得它是 MVC 版本特定的还是持久的。基本上,如果您使用 TextBoxFor
,则不会应用 "required" 客户端验证。您需要使用 EditorFor
或使用 @Html.TextBoxFor(m => m.Foo, new { required = true })
.
我认为您仍然会遇到如上所述最初未验证该字段的问题,但进行更改应确保它实际上被客户端验证捕获,而不是首先返回到服务器。