2010-03-06 11 views
21

Per quanto ne so, System.ComponentModel.DataAnnotations.DataTypeAttribute non funziona nella convalida del modello in MVC v1. Ad esempio,La convalida DataTypeAttribute funziona in MVC2?

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

Nei codici di cui sopra, la proprietà di posta elettronica non verrà convalidata in MVC v1. Funziona con MVC v2?

risposta

36

[DataType("EmailAddress")] non influenza la convalida di default. Questo è IsValid modalità di questo attributo (da riflettore):

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

Questo è esempio di personalizzato DataTypeAttribute per convalidare Messaggi di posta elettronica (tratto da questo sito 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

Grazie per questo. –

+0

Penso che si voglia rendere statica la regex perché l'impostazione dell'opzione compilata può causare la compilazione dovunque l'attributo sia utilizzato e, se la memoria lo serve, generare ogni volta un nuovo assembly in memoria. –

+0

@ Mike Scott: nuovo assemblaggio in memoria? Che cosa vuoi dire con questo? – LukLed

13

Come LukLed pointed out, DataTypeAttribute non esegue alcuna convalida per impostazione predefinita. Ma influenza i modelli su come vengono presentati i dati.

Ad esempio se si chiama il metodo Html.DisplayFor() su un modello con attributo DataType(DataType.EmailAddress), verrà formattato il suo valore con <a href="mailto:{0}">{0}</a> (almeno in MVC RC2).

+2

Grazie per punto che è DataTypeAttribute non un attributo di convalida. – wenqiang

+1

@Wayne: In realtà è ValidationAttribute. Si eredita da ValidationAttribute, ma restituisce sempre true. Puoi sovrascrivere il metodo IsValid e definirne il tuo, come nella soluzione di David Hayden. – LukLed

+0

@LukLed, infatti eredita da ValidationAttribute. Mi chiedo perché. Ad ogni modo, correggerò quella parte. –

8

In alternativa, è possibile utilizzare direttamente l'attributo RegularExpression sul proprio campo invece di creare il proprio attributo che alla fine andrà a verificare la corrispondenza di espressioni regolari.

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

partire da NET 4.5 c'è EmailAddressAttribute, che ha una corretta attuazione del metodo IsValid. Quindi, se hai come target .NET 4.5, per la convalida, ti preghiamo di considerare l'utilizzo di EmailAddressAttribute invece di uno personalizzato. Ad esempio,

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

E se siete curiosi di sapere l'attuazione di EmailAddressAttribute, quindi ecco il decompilato (utilizzando JetBrains dotPeek decompilatore) fonte della classe:

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; 
    } 
    } 
} 
Problemi correlati