2010-03-06 11 views
21

Por lo que sé, System.ComponentModel.DataAnnotations.DataTypeAttribute no funciona en la validación del modelo en MVC v1. Por ejemplo,¿Funciona la validación de DataTypeAttribute en MVC2?

public class Model 
{ 
    [DataType("EmailAddress")] 
    public string Email {get; set;} 
} 

En los códigos anteriores, la propiedad Correo electrónico no se validará en MVC v1. ¿Está funcionando en MVC v2?

Respuesta

36

[DataType("EmailAddress")] no influye en la validación por defecto. Esta es IsValid método de este atributo (de reflector):

public override bool IsValid(object value) 
{ 
    return true; 
} 

Este es un ejemplo de la costumbre DataTypeAttribute para validar correos electrónicos (tomado de este sitio http://davidhayden.com/blog/dave/archive/2009/08/12/CustomDataTypeAttributeValidationCustomDisplay.aspx):

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] 
public class EmailAddressAttribute : DataTypeAttribute 
{ 
    private readonly Regex regex = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", RegexOptions.Compiled); 

    public EmailAddressAttribute() : base(DataType.EmailAddress) 
    { 

    } 

    public override bool IsValid(object value) 
    { 

     string str = Convert.ToString(value, CultureInfo.CurrentCulture); 
     if (string.IsNullOrEmpty(str)) 
      return true; 

     Match match = regex.Match(str); 
     return ((match.Success && (match.Index == 0)) && (match.Length == str.Length)); 
    } 
} 
+0

Gracias por esto. –

+0

Creo que desea hacer que la expresión regular estética porque la configuración de la opción compilada puede hacer que la compilación se realice dondequiera que se use el atributo y, si la memoria sirve, generando un nuevo conjunto en memoria cada vez. –

+0

@Mike Scott: ¿Nuevo conjunto en memoria? ¿Qué quieres decir con eso? – LukLed

13

Como LukLed pointed out, DataTypeAttribute no realiza ninguna validación por defecto. Pero sí influye en las plantillas con respecto a cómo se presentan los datos.

Por ejemplo, si se llama a Html.DisplayFor() método en un modelo que tiene DataType(DataType.EmailAddress) atributo, se dará formato con su valor <a href="mailto:{0}">{0}</a> (al menos en MVC RC2).

+2

Gracias por el punto de que es DataTypeAttribute no es un atributo de validación – wenqiang

+1

@Wayne: en realidad es ValidationAttribute. Hereda de ValidationAttribute, pero siempre devuelve verdadero. Puede anular el método IsValid y definir el suyo, como lo hace la solución de David Hayden. – LukLed

+0

@LukLed, de hecho hereda de ValidationAttribute. Me pregunto porque. De todos modos, corregirá esa parte. –

8

Como alternativa, puede usar directamente el atributo RegularExpression en su campo en lugar de crear su propio atributo que al final va a verificar si hay una coincidencia de expresiones regulares.

[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = PaErrorMessages.InvalidEmailAddress)] 
public string Email { get; set; } 
2

A partir de .NET 4.5 no es EmailAddressAttribute, que tiene una aplicación correcta del método IsValid. Por lo tanto, si está orientando .NET 4.5, luego para la validación considere usar el EmailAddressAttribute en lugar de uno personalizado. Por ejemplo,

public class Model 
{ 
    [EmailAddress(ErrorMessage = "INVALID EMAIL")] 
    public string Email {get; set;} 
} 

Y si eres curioso acerca de la implementación de EmailAddressAttribute, entonces aquí es la descompilación (usando JetBrains dotPeek decompilador) fuente de la clase:

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; 
    } 
    } 
} 
Cuestiones relacionadas