Gruppi di route, parametri e convalida
Organizzi gli endpoint con MapGroup, associ i parametri di route, query e body e li convalidi con le annotazioni dei dati.
Gruppi di route, parametri e convalida è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Gruppi di route per l'organizzazione
MapGroup() (introdotto in .NET 7) consente di raggruppare endpoint correlati sotto un prefisso comune e di applicare una configurazione condivisa — middleware, criteri di autorizzazione, tag — senza ripeterla per ogni endpoint.
Creare un gruppo di route
Chiami app.MapGroup("/api/products") e quindi mappi gli endpoint sul gruppo restituito. Il prefisso viene aggiunto automaticamente a tutte le route.
var products = app.MapGroup("/api/products").WithTags("Products");
products.MapGet("/", GetAll);
products.MapGet("/{id}", GetById);
products.MapPost("/", Create);
products.MapPut("/{id}", Update);
products.MapDelete("/{id}", Delete);
// Routes: /api/products, /api/products/{id}Applicare l'autenticazione a un gruppo
Utilizzi RequireAuthorization() sul gruppo per proteggere tutti gli endpoint in una sola volta. I singoli endpoint possono comunque sovrascrivere questa impostazione con AllowAnonymous().
var adminGroup = app.MapGroup("/admin")
.RequireAuthorization("AdminPolicy")
.WithTags("Admin");
adminGroup.MapGet("/users", GetAllUsers);
adminGroup.MapDelete("/users/{id}", DeleteUser);
// This one inside the group opts out
adminGroup.MapGet("/status", () => "OK").AllowAnonymous();Vincoli sui parametri di route
Limiti i parametri di route con schemi di tipo. Il router rifiuta le richieste che non corrispondono, restituendo automaticamente 404.
// Only matches numeric IDs
app.MapGet("/products/{id:int}", (int id) => id);
// GUID constraint
app.MapGet("/orders/{orderId:guid}", (Guid orderId) => orderId);
// Length constraint
app.MapGet("/codes/{code:length(6)}", (string code) => code);
// Min value
app.MapGet("/page/{page:min(1)}", (int page) => page);Binding da origini diverse
I parametri vengono associati a origini diverse tramite attributi. Per impostazione predefinita, i tipi semplici provengono dalla route o dalla query string, mentre i tipi complessi provengono dal body.
app.MapPost("/search", (
[FromQuery] string q,
[FromQuery] int page,
[FromHeader(Name = "X-Api-Version")] string version,
[FromBody] SearchFilters filters,
AppDbContext db) =>
{
// q and page from query string
// version from request header
// filters from JSON body
return Results.Ok();
});Binding di parametri personalizzati con TryParse
Per i tipi personalizzati utilizzati come parametri di route o di query, implementi un metodo statico TryParse. Il framework lo chiama automaticamente per analizzare il valore stringa.
public record ProductFilter(string? Category, decimal? MinPrice)
{
public static bool TryParse(string value, out ProductFilter result)
{
var parts = value.Split(':');
result = new ProductFilter(
parts.Length > 0 ? parts[0] : null,
parts.Length > 1 && decimal.TryParse(parts[1], out var p) ? p : null);
return true;
}
}
// Usage: GET /products?filter=Electronics:50
app.MapGet("/products", ([FromQuery] ProductFilter filter) => filter);Convalida con le annotazioni dei dati
Decori i DTO delle richieste con attributi di annotazione dei dati. Nelle Minimal API, utilizzi l'interfaccia IValidatableObject o un filtro di convalida per attivare la convalida.
using System.ComponentModel.DataAnnotations;
record CreateProductRequest
{
[Required, MaxLength(200)]
public string Name { get; init; } = "";
[Range(0.01, 999999)]
public decimal Price { get; init; }
[Range(0, int.MaxValue)]
public int Stock { get; init; }
}Filtri degli endpoint per la convalida
I filtri degli endpoint vengono eseguiti prima o dopo il gestore. Li utilizzi per aggiungere la convalida del modello e rifiutare le richieste non valide prima che raggiungano la logica di business.
app.MapPost("/products", CreateProduct)
.AddEndpointFilter(async (ctx, next) =>
{
var req = ctx.GetArgument<CreateProductRequest>(0);
var errors = new List<ValidationResult>();
if (!Validator.TryValidateObject(req,
new ValidationContext(req), errors, true))
{
return Results.ValidationProblem(
errors.ToDictionary(e => e.MemberNames.First(),
e => new[] { e.ErrorMessage! }));
}
return await next(ctx);
});Integrazione con FluentValidation
Per regole di convalida complesse, utilizzi FluentValidation con il pacchetto SharpGrip.FluentValidation.AutoValidation.Endpoints per la convalida automatica nelle Minimal API.
public class CreateProductValidator : AbstractValidator<CreateProductRequest>
{
public CreateProductValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
RuleFor(x => x.Price).GreaterThan(0);
RuleFor(x => x.Stock).GreaterThanOrEqualTo(0);
}
}
builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblyContaining<CreateProductValidator>();Gruppi di route annidati
I gruppi di route possono essere annidati per rappresentare risorse gerarchiche, ad esempio ordini contenenti voci d'ordine.
var api = app.MapGroup("/api").RequireAuthorization();
var orders = api.MapGroup("/orders");
orders.MapGet("/", GetAllOrders);
orders.MapGet("/{id:int}", GetOrder);
// Nested: /api/orders/{orderId}/lines
var lines = orders.MapGroup("/{orderId:int}/lines");
lines.MapGet("/", GetOrderLines);
lines.MapPost("/", AddOrderLine);
lines.MapDelete("/{id}", RemoveOrderLine);Esempio reale: gruppo di API con versioning
Raggruppi gli endpoint per versione dell'API per supportare il versioning affiancato, senza duplicare la configurazione dell'autenticazione o dei tag.
var v1 = app.MapGroup("/api/v1")
.RequireAuthorization()
.WithTags("v1");
var v2 = app.MapGroup("/api/v2")
.RequireAuthorization()
.WithTags("v2");
v1.MapGet("/products", GetProductsV1);
v2.MapGet("/products", GetProductsV2); // richer responseVerifica rapida
Qual è lo scopo di MapGroup() nelle Minimal API?
Riepilogo: gruppi di route, parametri e convalida
Punti chiave:
MapGroup(): condivide prefisso e configurazione tra più endpoint- I vincoli di route (
:int,:guid,:min) rifiutano automaticamente le route non corrispondenti [FromQuery],[FromHeader],[FromBody]specificano esplicitamente l'origine del binding- Implementi
TryParsenei tipi personalizzati per il binding automatico di route e query - I filtri degli endpoint consentono di gestire aspetti trasversali come la convalida
Domande Frequenti
La lezione «Gruppi di route, parametri e convalida» è gratuita?
Sì — il testo completo di «Gruppi di route, parametri e convalida» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Gruppi di route, parametri e convalida»?
Organizzi gli endpoint con MapGroup, associ i parametri di route, query e body e li convalidi con le annotazioni dei dati. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Gruppi di route, parametri e convalida»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Creazione della prima Minimal API
- Gruppi di route, parametri e convalida
- Middleware e filtri nelle Minimal API
- OpenAPI, versionamento e distribuzione