6

Sto provando ad ereditare lo RegularExpressionAttribute per migliorare la riusabilità con la convalida di SSN.tenta di ereditare RegularExpressionAttribute, non convalida più

ho il seguente modello:

public class FooModel 
{ 
    [RegularExpression(@"^(?!000)(?!666)(?!9[0-9][0-9])\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}$", ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank")] 
    public string Ssn { get; set; } 
} 

che convalida correttamente sul client e server. Volevo incapsulare che lungo espressione regolare nella propria convalida attribuiscono questo modo:

public class SsnAttribute : RegularExpressionAttribute 
{ 
    public SsnAttribute() : base(@"^(?!000)(?!666)(?!9[0-9][0-9])\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}$") 
    { 
     ErrorMessage = "SSN is invalid"; 
    } 
} 

poi ho cambiato FooModel in questo modo:

public class FooModel 
{ 
    [Ssn(ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank")] 
    public string Ssn { get; set; } 
} 

Ora la convalida non rende i dati discreti attributi il cliente. Non sono abbastanza sicuro del perché, poiché sembra che i due dovrebbero essere essenzialmente la stessa cosa.

Qualche suggerimento?

risposta

13

Nel vostro Application_Start aggiungere la seguente riga di associare un adapater al tuo attributo personalizzato che sarà responsabile per l'emissione della convalida lato client attributi:

DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(SsnAttribute), 
    typeof(RegularExpressionAttributeAdapter) 
); 

Il motivo per cui avete bisogno di questo è il modo RegularExpressionAttribute è implementato . Non implementa l'interfaccia IClientValidatable ma ha piuttosto uno RegularExpressionAttributeAdapter ad esso associato.

Nel tuo caso si ha un attributo personalizzato che deriva da RegularExpressionAttribute ma l'attributo non implementa l'interfaccia IClientValidatable in modo che convalida del client di lavorare né possiede un adattatore attributo associato ad esso (in contrasto con la sua classe genitore) . Quindi il tuo SsnAttribute dovrebbe implementare l'interfaccia IClientValidatable o avere un adattatore associato come suggerito in precedenza nella mia risposta.

Detto questo personalmente, non vedo molto nell'implementazione di questo attributo di convalida personalizzato. Una costante potrebbe essere sufficiente in questo caso:

public const string Ssn = @"^(?!000)(?!666)(?!9[0-9][0-9])\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}$", ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank"; 

e poi:

public class FooModel 
{ 
    [RegularExpression(Ssn, ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank")] 
    public string Ssn { get; set; } 
} 

sembra abbastanza leggibile.

+2

Ho finito con il mio attributo implementare 'IClientValidatable'. Il motivo per cui volevo un attributo per questo invece di usare un 'RegularExpressionAttribute' era principalmente perché non volevo capire dove mettere una regex 'const const pubblica 'nel mio progetto ([ci sono solo due cose difficili in Computer Science ...] (http://martinfowler.com/bliki/TwoHardThings.html)), ma anche perché sembrava esserci un modello emergente da parte degli MVC per creare attributi che in pratica non sono più di un "RegularExpressionAttribute" (' PhoneAttribute ', 'EmailAddressAttribute', ecc.), Quindi mi sono sentito giustificato –

Problemi correlati