2013-04-19 16 views
9

Ho un [EmailAddress] DatiAnnotazione da .net 4.5 su una proprietà del modello, che restituisce un 'Il campo di posta elettronica non è un indirizzo di posta elettronica valido. 'errore durante la convalida, quando la proprietà Email è vuota.EmailAddressAttributo senza necessità

Sebbene ciò sia tecnicamente vero, mi sarei aspettato che questo valore vuoto venisse rilevato solo con un'annotazione [Required].

C'è qualche parametro che mi manca che può essere passato all'annotazione [EmailAddress] per consentire alle stringhe vuote di convalidare o devo ricorrere all'utilizzo di un'espressione regolare del validatore personalizzato?

risposta

7

Non esiste alcun parametro per EmailAddressAttribute. Il codice di convalida per questo attibute è la seguente:

if (value == null) 
{ 
    return true; 
} 
string input = value as string; 
return ((input != null) && (_regex.Match(input).Length > 0)); 

E l'espressione regolare è definita come (non ci sarà alcuna corrispondenza per stringa vuota):

_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.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase); 

per raggiungere il tuo obiettivo è possibile creare il grado di ereditare da DataTypeAttribute sostituisce il metodo IsValid, quindi restituirà true per stringhe vuote o null e utilizzerà l'istanza di EmailAddressAttribute. Questo dovrebbe essere qualcosa del tipo:

public override bool IsValid(object value) 
{ 
    if (value == null) 
    { 
     return true; 
    } 
    string input = value as string; 
    var emailAddressAttribute = new EmailAddressAttribute(); 

    return (input != null) && (string.IsNullOrEmpty(input) || emailAddressAttribute.IsValid(input)); 
} 
+2

* Per raggiungere il tuo obiettivo puoi ereditare da EmailAddressAttribute * Quella classe è 'sealed'. Devi usare la composizione. –

+1

Anche "valore come stringa" seguito da "IsNullOrEmpty" tratterà i valori che non sono stringhe come indirizzi email. Per esempio. '5.5M' è un indirizzo email, secondo questa implementazione di' IsValid'. –

+1

@ ta.speot.è un buon punto! E tu sei totalmente corretto sui valori non stringa. Ho esteso la mia risposta con l'implementazione che tiene conto del tipo di parametro passato. –

0

L'altro modo è semplicemente chiamare l'API in modo diverso. Per JSON chiedere al chiamante di fornire "Email": null o non includere questa proprietà nel corpo. Per XML chiedi al chiamante che fornisce l'elemento vuoto <Email></Email> per rimuovere questo elemento dal corpo del messaggio se l'e-mail non è disponibile.

Se la proprietà JSON è nullo o non presente o l'elemento XML non è presente, il campo nel modello diventa nullo e pertanto non genera l'errore di convalida perché non è presente a meno che non sia stato aggiunto [Required]. In questo modo guidi richiesto o no.

In alcuni casi, capisco che "pigro" o chiamante non autorizzato voglia sempre inviare lo stesso corpo con valore vuoto, specialmente per XML. "Sto inviando questo <Email></Email> perché il mio cliente non mi ha fornito l'e-mail"

Problemi correlati