我正在尝试MVC的数据类型属性,并创建了一个简单的场景,如下所示:
视图:
@model MVC4.Models.Model
@{
ViewBag.Title = "DataTypeAttribute";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<h2>DataTypeAttribute</h2>
@using (Html.BeginForm("SubmitData", "Home"))
{
<div>
@Html.ValidationSummary()
</div>
@Html.EditorFor(m => m.Email)
<br />
<br />
@Html.EditorFor(m => m.PostalCode)
<br />
<br />
@Html.EditorFor(m => m.TextOnly)
<br />
<br />
<button type="submit">Submit</button>
}
模型:
public class Model
{
[DataType(DataType.EmailAddress)]
[Required]
//[EmailAddress]
public string Email { get; set; }
[DataType(DataType.PostalCode)]
public string PostalCode { get; set; }
public string TextOnly { get; set; }
}
"SubmitData"只是一个控制器,如果ModelState.IsValid为false,则返回View(…,model)。
尽管像这样的帖子很好地解决了Html.TextBoxFor和Html.EditorFor之间的差异,但我找不到为什么在使用TextBoxFor时,对数据类型EmailAddress的验证无效的答案。我确实发现有人提到TextBoxFor没有考虑元数据,而EditorFor考虑了元数据。
但这有道理吗?所以TextBoxFor不支持客户端验证?!
我想知道两者之间的区别是什么原因?
TextBoxFor()
确实可以进行验证。
[DataType(DataType.EmailAddress)]
不是验证属性。它是一个属性,通过在渲染的html中设置type
属性来确定要显示的输入类型。例如<input type="text" ..>
、<input type="date" ..>
、<input type="email" ..>
,以便呈现浏览器实现的HTML4日期选择器、电子邮件输入等。它仅适用于EditorFor()
,因为TextBoxFor()
作为其名称建议使用type="text"
生成和输入
如果要验证电子邮件地址,请在属性中使用[EmailAddress]
属性。
[Required]
[EmailAddress]
public string Email { get; set; }
编辑(进一步评论)
HTML5的一个特性是能够在不依赖脚本的情况下验证用户数据。一种这样的浏览器验证形式是使用type
属性。在用@Html.EditorFor()
呈现的属性上使用[DataType(DataType.EmailAddress)]
将type="email"
添加到input
元素中。来自MDN文档
email:元素表示一个电子邮件地址。换行符会自动从输入值中删除。可以设置无效的电子邮件地址,但只有当电子邮件地址满足ABNF production 1*(atext/".")"@"ldh str 1*("."ldh str)时,输入字段才会满足其约束,其中atext在RFC 5322第3.2.3节中定义,ldh str在RFC 1034第3.5节中定义。
如果您当前看到与该属性相关联的验证错误消息,并且尚未添加[EmailAddress]
属性,则意味着未加载jquery.validate.js
,并且您看到与type="email"
相关联的浏览器错误消息。
当(正确地)加载jquery.validate.js
时,novalidate="novalidate"
属性将添加到form
元素中,该元素指定表单在提交时不进行验证(使用HTML5验证)。jquery.validate.js
的相关代码是(大约第35行)
// Add novalidate tag if HTML5.
this.attr('novalidate', 'novalidate');
添加此项是为了防止浏览器验证和jquery非侵入性验证显示的错误消息之间可能出现混淆。
关于为什么DataTypeAttribute
属性在实际上不进行验证的情况下继承ValidationAttribute,来自Brad Wilson本人在这个答案中的
它从ValidationAttribute派生的原因是,您可以创建一个新的自定义数据类型类,该类既是DataType又是Validation,全部封装为一个类。这是.NET不允许多重继承的不幸副作用。