Come sappiamo, ASP.NET Core effettua automaticamente la validazione del model in input in base alle data annotation. Questo fa sì che, per esempio, se non riceviamo alcun valore per una proprietà marcata come Required, il ModelState sarà marcato come invalid.
public class Customer
{
[Required]
public string Name { get; set; }
}
public class CustomersController: ControllerBase
{
public void Post([FromBody] Customer value)
{
if (!this.ModelState.IsValid)
{
// sarà false se Name è null
}
}
}
In casi più complessi, che non possiamo esprimere con il solo uso degli attribute, possiamo implementare l'interfaccia IValidatableObject e implementare la nostra logica di validazione all'interno del metodo Validate.
public class Customer : IValidatableObject
{
[Required]
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// .. logica qui ..
}
}
Il runtime di ASP.NET Core eseguirà automaticamente quest'ultimo - anche se solo nel caso in cui tutte le data annotation siano verificate - e utilizzerà il risultato per restituire un eventuale elenco di errori all'utente.
Un aspetto interessante è che, durante la sua esecuzione, possiamo eventualmente anche sfruttare i servizi applicativi registrati nell'IoC container di ASP.NET Core, per esempio per effettuare dei controlli sul database. Immaginiamo per esempio di avere una proprietà CityId e di voler verificare che l'identificativo esista. Possiamo scrivere un codice simile al seguente:
public class Customer : IValidatableObject
{
public int CityId { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var cityService = (ICityService)validationContext.GetService(typeof(ICityService));
if (cityService.FindCityById(this.CityId) == null)
{
yield return new ValidationResult("The city doesn't exist", new[] { "CityId" });
}
else
{
yield return ValidationResult.Success;
}
}
}
Con il metodo GetService di validationContext, infatti, possiamo recuperare un'istanza del servizio necessario e sfruttarla per fare le nostre verifiche del caso.
Purtroppo non esiste un overload generico di questo metodo, cosa che rende il suo utilizzo un po' più macchinoso di quanto ci aspetteremmo. Tuttavia possiamo facilmente implementarlo come nello snippet in basso:
internal static class ValidationContextExtensions
{
public static T GetService<T>(this ValidationContext validationContext)
{
if (validationContext == null)
{
throw new ArgumentNullException(nameof(validationContext));
}
return (T)validationContext.GetService(typeof(T));
}
}
In questo modo potremo usare la ben più comoda sintassi generica:
var cityService = validationContext.GetService<ICityService>();
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Change tracking e composition in Entity Framework
Ordine e importanza per @layer in CSS
Ricevere notifiche sui test con Azure Load Testing
Ottenere un token di accesso per una GitHub App
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Utilizzare DeepSeek R1 con Azure AI
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Utilizzare EF.Constant per evitare la parametrizzazione di query SQL
Collegare applicazioni server e client con .NET Aspire
Utilizzare Hybrid Cache in .NET 9
Creare una custom property in GitHub
I più letti di oggi
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!