Le DataAnnotation sono un sistema standard, nel .NET Framework, per esprimere regole validazione tramite una sintassi basata su attributi. I diversi modelli di sviluppo che oggi abbiamo a disposizione, ad esempio ASP.NET Dynamic Data Controls o ASP.NET MVC (dalla versione 2), sono in grado poi di interpretare questo codice dichiarativo, applicando le varie regole per determinare se l'input dell'utente sia valido o meno.
In ASP.NET MVC, ad esempio, è sufficiente decorare il model User come segue
public class User { [Required] public string Username { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [Required] [DataType(DataType.Password)] [Compare("Password")] public string ConfirmPassword { get; set; } }
e successivamente interrogare la proprietà ModelState.IsValid, per far sì che il framework verifichi che:
- tutte le proprietà siano popolate, visto che tutte sono marcate come Required;
- il contenuto dell proprietà ConfirmPassword corrisponda a quello di Password, come specificato dall'attributo Compare.
La più grande potenzialità delle DataAnnotation è però costituita dalla possibilità di realizzare attributi personalizzati per implementare le proprie regole di validazione. Supponiamo ad esempio che, per ragioni di sicurezza, vogliamo fare in modo che la password contenga almeno uno tra alcuni simboli specificati. Per questi scopi può sicuramente tornare utile l'attributo RegularExpressionAttribute, che effettua una validazione in base ad una regular expression fornita come parametro. Alternativamente, però, volendo avvalersi di una sintassi più semplice, possiamo pensare di realizzarne una nostra versione, così che possiamo sfruttarla in maniera simile alla seguente:
[Required] [MustContain("!£$%")] [DataType(DataType.Password)] public string Password { get; set; }
Per raggiungere questo scopo è sufficiente creare una classe che erediti da ValidationAttribute, come nell'esempio:
public class MustContainAttribute : ValidationAttribute { public string Chars { get; set; } public MustContainAttribute(string chars) // Messaggio di default : base("Il campo {0} deve contenere almeno un carattere tra {1}") { this.Chars = chars; } }
Essa definisce una proprietà Chars, inizializzata tramite il costruttore, che utilizzeremo per memorizzare l'elenco dei caratteri richiesti. La regola di validazione vera e propria, invece, può essere implementata effettuando l'override del metodo IsValid:
protected override ValidationResult IsValid( object value, ValidationContext validationContext) { var stringValue = value as string; if (stringValue.Any(c => Chars.Contains(c))) return null; return new ValidationResult( this.FormatErrorMessage(validationContext.DisplayName)); }
Questo metodo riceve in ingresso un parametro value, che contiene il dato che dobbiamo validare, più un ValidationContext tramite cui possiamo reperire, se necessarie, ulteriori informazioni relative all'operazione di validazione in atto, come l'istanza completa dell'oggetto o il nome della proprietà validata. La logica del metodo è molto semplice, e si limita a verificare, tramite l'extension method Any di LINQ, la presenza all'interno della stringa in input di almeno uno dei caratteri di Chars.
Nel caso la validazione fallisca, viene restituita un'istanza di ValidationResult contenente il messaggio d'errore. Quest'ultimo può essere eventalmente personalizzato effettuando l'override del metodo FormatErrorMessage, includendo ad esempio l'elenco dei caratteri richiesti oltre al nome della proprietà errata.
public override string FormatErrorMessage(string name) { return string.Format(this.ErrorMessageString, name, Chars); }
L'implementazione in alto, in particolare, genera il messaggio di errore utilizzando come template la proprietà ErrorMessageString. Essa, infatti, viene automaticamente popolata dalla classe base in base al valore di ErrorMessage, ErrorMessageResourceName ed ErrorMessageResourceType, se definiti dall'utente.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Bloccare l'esecuzione di un pod in mancanza di un'artifact attestation di GitHub
Filtrare i dati di una QuickGrid in Blazor con una drop down list
Hosting di componenti WebAssembly in un'applicazione Blazor static
Utilizzare il trigger SQL con le Azure Function
Gestire la cancellazione di una richiesta in streaming da Blazor
Recuperare l'ultima versione di una release di GitHub
Ordinare randomicamente una lista in C#
Migliorare l'organizzazione delle risorse con Azure Policy
Eseguire una query su SQL Azure tramite un workflow di GitHub
Migrare una service connection a workload identity federation in Azure DevOps
Triggerare una pipeline su un altro repository di Azure DevOps
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2024 - Milano
- .NET Conference Italia 2023 - Milano e Online