Nello script precedente, abbiamo introdotto l'utilizzo dei constraint come ulteriore mezzo di selezione delle route in ASP.NET Web API, facendo un esempio di route con un parametro Partita IVA e sfruttando i validatori built in per verificarne il contenuto numerico. Questo, però, non è sufficiente: la Partita Iva italiana contiene un carattere di controllo calcolato secondo un algoritmo che coinvolge le restanti cifre. Per criteri di validazione non banali come questo, possiamo scrivere un nostro route constraint personalizzato.
Aggiungiamo quindi una nuova classe al nostro progetto, implementando l'interfaccia IHttpRouteConstraint del namespace System.Web.Http.Routing.
Il metodo Match è il solo membro da implementare: possiede vari parametri che riguardano il contesto HTTP e restituisce un valore booleano che indicherà se la validazione ha avuto un buon esito.
public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection) { //Se il parametro non viene fornito o se è vuoto, allora //restituiamo false perché non possiamo reputarlo valido if (!values.ContainsKey(parameterName)) return false; var partitaIva = values[parameterName] as string; if (string.IsNullOrEmpty(partitaIva)) return false; //Con una espressione regolare, controlliamo che non //contenga altri caratteri se non 11 cifre esatte var regex = new Regex(@"^\d{11}$"); if (!regex.IsMatch(partitaIva)) return false; //Qui effettuiamo la validazione della Partita Iva italiana. //Il codice è omesso per brevità, ma possiamo utilizzare //quello descritto da http://it.wikipedia.org/wiki/Partita_IVA var controlChar = this.ComputeControlChar(partitaIva); //Il buon esito dipenderà dalla corrispondenza tra la cifra //di controllo C che abbiamo calcolato e l'ultima cifra della partita iva return controlChar == partitaIva.Substring(10, 1); }
A questo punto non ci resta che registrare il nostro constraint sul file App_Start/WebApiConfig.cs. Nel metodo Register, troveremo l'invocazione a MapHttpAttributeRoutes(), il metodo necessario ad abilitare l'attribute routing. Andiamo a sostituirla con le righe di codice seguenti:
var constraintResolver = new DefaultInlineConstraintResolver(); //Registriamo il nostro constraint indicando un nome constraintResolver.ConstraintMap.Add("piva", typeof(PartitaIvaConstraint)); config.MapHttpAttributeRoutes(constraintResolver);
Ora non resta che applicare il route constraint al parametro {partitaIva}, usando il nome scelto all'atto della registrazione.
[RoutePrefix("api/clienti/")] public class ClientiController : ApiController { [HttpGet, Route("{partitaIva:piva}")] public Cliente TrovaClientePerPartitaIva(string partitaIva) { ... } }
Usare un route constraint rappresenta un modo efficiente per far fronte a dati potenzialmente non validi. Se l'input non fosse conforme al vincolo, l'applicazione restituirebbe subito un errore 404, senza che la richiesta debba attraversare tutta la pipeline di ASP.NET WebAPI. Inoltre, i route constraint ci permettono di realizzare action sensibili al contesto: una seconda action di ricerca per codice fiscale potrebbe essere legata ad un URL con gli stessi segmenti (es. /api/clienti/{codiceFiscale}) ma, grazie ad un diverso route constraint, il motore di routing riuscirebbe facilmente a disambiguare le due action.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Ottimizzare il mapping di liste di tipi semplici con Entity Framework Core
Proteggere le risorse Azure con private link e private endpoints
Sfruttare MQTT in cloud e in edge con Azure Event Grid
Testare l'invio dei messaggi con Event Hubs Data Explorer
Gestire domini wildcard in Azure Container Apps
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Popolare una classe a partire dal testo, con Semantic Kernel e ASP.NET Core Web API
Usare un KeyedService di default in ASP.NET Core 8
Triggerare una pipeline su un altro repository di Azure DevOps
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Gestire i dati con Azure Cosmos DB Data Explorer