1

我想MVC的数据类型属性,就创建了一个简单的场景,像下面这样:为什么验证不能使用Html.TextBoxFor,而是使用Html.EditorFor?

查看

@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)。

尽管像this岗位做应对之间Html.TextBoxFor和Html.EditorFor差异一份好工作,我无法找到一个答案,为什么使用TextBoxFor时为数据类型EmailAddress的验证将无法正常工作。我确实发现人们提到TextBoxFor不考虑元数据,而EditorFor。

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

我想知道两者之间的区别是什么原因?

+0

总结答案:HTML 5引入的新输入类型,如添加自动验证。 TextBoxFor总是生成'text'类型的输入,因此不会生成内置的验证。另一方面,当为其生成html时,EditorFor将模型字段元数据(数据注释)考虑在内,因此标有“DataType(DataType.EmailAddress)”的字段将生成输入类型='email',因此新内置HTML 5验证以及它。 – Veverke

回答

3

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 documentation

电子邮件:该元素表示一个电子邮件地址。换行符会自动从输入值中删除。可以设置一个无效的电子邮件地址,但如果电子邮件地址满足ABNF生产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时,实际上它并不在this answer

从ValidationAttribute派生是如此,你可以创建一个新的自定义数据类型类的原因做验证,由布拉德·威尔逊本人,这是一个数据类型和一个验证,都包装成一个。这是.NET不允许多重继承的不幸副作用。

+0

起初你的答案看起来很有希望,但经过一些测试后,我可以说:1)使用[EmailAddress]和DataType(EmailAddress)具有完全相同的效果。换句话说,你说DataType不是一个验证属性,但它确实在这种情况下添加验证。 2)在两种情况下使用DataType(Text)或PostalCode创建输入类型为“text”的输入,并且看起来是相同的......如果验证没有受到影响,那么使用它们有什么意义?在这种情况下,我们事先知道我们将最终输入文本...... – Veverke

+0

不,它不。我看到你拥有的唯一脚本是'jquery.validate.unobtrusive.min.js',它本身不会做任何事情。你需要'jquery.js'和'jquery.validate.js'和'jquery.validate.unobtrusive.js'(按照这个顺序)。我还建议您使用与每个控件关联的@ Html.ValidationMessageFor(),并将@ Html.ValidationSummary()更改为@ Html.ValidationSummary(true) –

+0

您还应该检查生成的html。验证属性为呈现的html添加各种'data-val'属性。所有'[DataType]'属性都设置了相应的'type'属性 –

相关问题