19

Sto utilizzando il framework CodeFirst Entitty 5. Ho una classe che rappresenta un utente.Consenti stringhe vuote per i campi contrassegnati con PhoneAttribute o UrlAttribute

public class User 
{ 
    [Key] 
    public int UserId { get; set; } 

    [Url] 
    [DataType(DataType.Url)] 
    [Required(AllowEmptyStrings= true)] 
    public string WebSite { get; set; } 

    [Phone] 
    [DataType(DataType.PhoneNumber)] 
    [Required(AllowEmptyStrings = true)] 
    public string Phone { get; set; } 

    [Phone] 
    [DataType(DataType.PhoneNumber)] 
    [Required(AllowEmptyStrings = true)] 
    public string Fax { get; set; } 
} 

mi piace la meccanica di convalida per Phone e Url attributi molto, ma purtroppo convalida non riesce quando i campi contrassegnati con questi attributi sono stringhe vuote, che io in realtà voglio permettere. [Required(AllowEmptyStrings = true)] non sembra funzionare con gli attributi Phone o Url. Lo stesso sembra essere applicato ad alcuni altri attributi DataAnnotations come EmailAddress.

C'è un modo per consentire stringhe vuote per i campi contrassegnati con tali attributi?

risposta

17

convalida attributi come [Phone] e [EmailAddress] controllerà eventuali valori stringa non nulli. Poiché il tipo string è intrinsecamente nullable, le stringhe vuote passate a ModelBinder vengono lette come null, che supera il controllo di convalida.

Quando si aggiunge l'attributo [Required], la stringa diventa effettivamente non annullabile. (Se si utilizza Code First, EF scriverà una colonna di database non annullabile.) ModelBinder interpreterà ora un valore vuoto come String.Empty - che non riuscirà a controllare la validazione degli attributi.

Quindi non v'è alcun modo per consentire vuote stringhe con gli attributi di convalida, ma è possibile consentire nulla stringhe. Tutto quello che devi fare è rimuovere l'attributo [Required]. I valori vuoti saranno null e i valori non vuoti verranno convalidati.

Nel mio caso, sto importando record da un file CSV e ho riscontrato questo problema perché stavo saltando il normale ModelBinder. Se stai facendo qualcosa di insolito come questo, essere sicuri di includere un controllo manuale prima di salvare per il vostro modello di dati:

Email = (record.Email == String.Empty) ? null : record.Email 
+0

non stavo utilizzando il modello Binder. Stavo scrivendo un importatore di dati e i dati di origine contengono email e telefoni vuoti. Credo che dovrei solo convertire stringhe vuote da sorgente a null allora. Grazie per la spiegazione! –

+1

@ Nu-hin. Il tuo DBA ti ringrazierà in futuro se sarai in grado di ripulire ambigui valori inutili come stringhe vuote e di sostituirli con null. Null è indefinito o sconosciuto. Un numero di telefono stringa vuoto non è definito o sconosciuto. È sempre divertente lavorare su un db anni dopo e trovare un mix di stringhe vuote, vuote, stringhe di spazi bianchi e il sempre utile "NESSUN NUMERO DI TELEFONO" nel campo del numero di telefono. –

+0

Questo sembra abbastanza inutile. Sì in * alcune * situazioni, l'assenza di un valore significa "non noto", ma "Decisamente vuoto" significa qualcosa di molto diverso da "Non noto". Quindi ci sono casi in cui una stringa vuota non è un "valore inutile". –

24

Utilizzare i seguenti annotazioni di due dati:

[Required(AllowEmptyStrings = true)] 
[DisplayFormat(ConvertEmptyStringToNull = false)] 
+0

Questo totalmente ha funzionato per me su EF6, grazie! –

+0

Funziona molto bene, ma mi chiedo perché Visual ha generato nel mio caso [Required] [StringLength (10)] se non ho null, nvarchar (10) –

+0

Rimuovere questo "[DisplayFormat (ConvertEmptyStringToNull = false)]" ha funzionato per me . Grazie – HGMamaci