C# DataTypeAttribute验证是否在MVC2中工作?
据我所知,System.ComponentModel.DataAnnotations.DataTypeAttribute在MVC v1的模型验证中不起作用。比如说,C# DataTypeAttribute验证是否在MVC2中工作?,c#,asp.net-mvc,validation,email,data-annotations,C#,Asp.net Mvc,Validation,Email,Data Annotations,据我所知,System.ComponentModel.DataAnnotations.DataTypeAttribute在MVC v1的模型验证中不起作用。比如说, public class Model { [DataType("EmailAddress")] public string Email {get; set;} } public class Model { [EmailAddress(ErrorMessage = "INVALID EMAIL")] publ
public class Model
{
[DataType("EmailAddress")]
public string Email {get; set;}
}
public class Model
{
[EmailAddress(ErrorMessage = "INVALID EMAIL")]
public string Email {get; set;}
}
在上面的代码中,电子邮件属性将不会在MVC v1中验证。它在MVC v2中工作吗?与此类似,默认情况下DataTypeAttribute不进行任何验证。但它确实会影响有关数据呈现方式的模板
例如,如果在具有数据类型(DataType.EmailAddress)
属性的模型上调用Html.DisplayFor()
方法,它将使用
格式化其值(至少在MVC RC2中是这样)。[DataType(“EmailAddress”)]
默认情况下不会影响验证。这是此属性的IsValid
方法(来自反射器):
这是用于验证电子邮件的自定义DataTypeAttribute示例(取自此网站):
查看Scott Guthrie关于MVC 2验证的博客文章。非常好。
或者,您可以直接在字段上使用RegularExpression属性,而不是创建自己的属性,该属性最终将检查正则表达式匹配
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = PaErrorMessages.InvalidEmailAddress)]
public string Email { get; set; }
从.NET 4.5开始,有,它正确地实现了
IsValid
方法。因此,如果您的目标是.NET 4.5,那么为了验证,请考虑使用“代码> EMAADADESREST属性< /代码>,而不是自定义的。比如说,
public class Model
{
[DataType("EmailAddress")]
public string Email {get; set;}
}
public class Model
{
[EmailAddress(ErrorMessage = "INVALID EMAIL")]
public string Email {get; set;}
}
如果您对EmailAddressAttribute
的实现感到好奇,那么下面是该类的反编译(使用反编译器)源代码:
using System;
using System.ComponentModel.DataAnnotations.Resources;
using System.Text.RegularExpressions;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class EmailAddressAttribute : DataTypeAttribute
{
private static Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
static EmailAddressAttribute()
{
}
public EmailAddressAttribute()
: base(DataType.EmailAddress)
{
this.ErrorMessage = DataAnnotationsResources.EmailAddressAttribute_Invalid;
}
public override bool IsValid(object value)
{
if (value == null)
return true;
string input = value as string;
if (input != null)
return EmailAddressAttribute._regex.Match(input).Length > 0;
else
return false;
}
}
}
感谢您指出DataTypeAttribute不是验证属性。@韦恩:它实际上是ValidationAttribute。它继承自ValidationAttribute,但始终返回true。您可以重写IsValid方法并定义自己的方法,就像在David Hayden的解决方案中一样。@LukLed,它确实继承自ValidationAttribute。我想知道为什么。无论如何,将更正该部分。
DataAnnotationsModelValidator
将遍历每个ValidationAttribute。DataTypeAttribute是ValidationAttribute,因此可以很容易地继承和引入验证。定义自己的数据类型时,可以轻松添加验证。@LukLed,谢谢。我再次编辑了答案,以删除其中表示不用于验证的部分。我认为您希望将该正则表达式设置为静态,因为设置compiled选项可能会导致编译在每个使用属性的位置都进行,并且,如果内存可用,则每次都会生成一个新的内存中程序集。@Mike Scott:新的内存中程序集?你这是什么意思?LukLed,它在锡上写的是什么-一个在内存中动态创建的程序集;-)带有compiled选项的正则表达式将IL发送到内存中的程序集中。因此,为了确保每次调用都不会耗尽内存,应该保存已编译的regex实例并重用它。看。@Mike Scott:你说得对,但如果我没弄错的话,一个属性在每个类中只实例化一次,而不是每个对象。这意味着在实践中,成本非常小。然而,你是对的,它是静态的,没有成本。如果语言允许,应该是常量。@skrebbel,那么如果您将属性放在10个类上,这是否意味着该属性有10个实例化,因此为同一正则表达式创建了10个内存程序集?