Asp.net mvc 为什么验证不适用于Html.TextBoxFor,而适用于Html.EditorFor?

Asp.net mvc 为什么验证不适用于Html.TextBoxFor,而适用于Html.EditorFor?,asp.net-mvc,unobtrusive-validation,html.textboxfor,asp.net-mvc-helpers,Asp.net Mvc,Unobtrusive Validation,Html.textboxfor,Asp.net Mvc Helpers,我正在尝试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/jq

我正在尝试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,它将返回视图(…,model)

虽然像这样的帖子在解决Html.TextBoxFor和Html.EditorFor之间的差异方面做得很好,但我找不到一个答案来解释为什么在使用TextBoxFor时数据类型EmailAddress的验证不起作用。我确实发现有人提到TextBoxFor不考虑元数据,而EditorFor考虑元数据

但这有意义吗?所以TextBoxFor不支持客户端验证

我想知道这两者之间存在差异的原因是什么?

TextBoxFor()
可用于验证

[DataType(DataType.EmailAddress)]
不是验证属性。它是一个属性,通过在呈现的html中设置
type
属性来确定要显示的输入类型。例如,
,以呈现HTML4日期选择器、电子邮件输入等的浏览器实现。。它仅适用于
EditorFor()
,因为它的名称建议使用
type=“text”

如果要验证电子邮件地址,请在属性上使用
[EmailAddress]
属性

[Required]
[EmailAddress]
public string Email { get; set; }
编辑(进一步评论)

HTML5的一个特性是能够验证用户数据,而不依赖于脚本。浏览器验证的一种形式是使用
type
属性。在使用
@Html.EditorFor()
呈现的属性上使用
[DataType(DataType.EmailAddress)]
会将
type=“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”
属性添加到
表单
元素,该元素指定表单在提交时不进行验证(使用HTML5验证)。
jquery.validate.js
中的相关代码是(大约第35行)

这是为了防止浏览器验证和jquery非干扰性验证显示的错误消息之间可能出现混淆

至于为什么
DataTypeAttribute
attribute在实际上不进行验证时继承了ValidationAttribute,这是Brad Wilson自己在年提出的

它源于ValidationAttribute的原因是,您可以创建一个新的自定义数据类型类,该类既是数据类型又是验证,都封装在一个类中。这是.NET不允许多重继承的一个不幸的副作用


起初,您的答案看起来很有希望,但经过一些测试,我可以说:1)使用[EmailAddress]和数据类型(EmailAddress)具有完全相同的效果。换句话说,您说数据类型不是验证属性,但在本例中它确实添加了验证。2) 使用数据类型(文本)或PostalCode创建两种情况下都是“文本”的输入,并且看起来相同。。。如果验证不重要,那么使用它们有什么意义?在这种情况下,我们事先就知道,无论如何,我们最终都会得到文本输入……不,它不会。我看到您仅有的脚本是
jquery.validate.unobtrusive.min.js
,它本身完全不起任何作用。您需要
jquery.js
jquery.validate.js
jquery.validate.unobtrusive.js
(按顺序)。我还建议您使用与每个控件关联的
@Html.ValidationMessageFor()
,并将
@Html.ValidationSummary()
更改为
@Html.ValidationSummary(true)
,您还应该检查生成的Html。验证属性将各种
数据val
属性添加到呈现的html中。所有的
[DataType]
属性id是否设置了相应的
类型
属性对于呈现输入的文本和PostalCode等数据类型,哪些类型是文本?那么,这些数据类型的目的是什么?我建议您从中学习。数据类型属性不是验证属性,它们用于告诉视图引擎如何呈现HTML。在上面的示例中,DataType.Date属性仅将电影日期显示为日期,而不显示时间。例如,以下数据类型属性不验证数据的格式:总结答案:HTML5引入的新输入类型,例如添加自动验证。TextBoxFor始终生成“text”类型的输入,因此不会生成内置验证。另一方面,EditorFor在为模型字段元数据(数据注释)生成html时将其考虑在内,因此标记为“DataType(DataType.EmailAddress)”的字段将生成输入类型='email',从而生成新的内置html 5验证。
// Add novalidate tag if HTML5.
this.attr('novalidate', 'novalidate');