Vytváření webových rozhraní API pomocí ASP.NET Core
ASP.NET Core podporuje vytváření webových rozhraní API pomocí kontrolerů nebo minimálních rozhraní API. Kontrolery ve webovém rozhraní API jsou třídy, které odvozují z ControllerBase. Kontrolery se aktivují a vyřaďte na každý požadavek.
Tento článek ukazuje, jak kontrolery využívat ke zpracování požadavků webového rozhraní API. Informace o vytváření webových rozhraní API bez kontrolerů najdete v kurzu : Vytvoření minimálního rozhraní API s ASP.NET Core.
Třída ControllerBase
Webové rozhraní API založené na kontroleru se skládá z jedné nebo několika tříd kontrolerů, které odvozují z ControllerBase. Šablona projektu webového rozhraní API poskytuje počáteční kontroler:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Kontrolery webového rozhraní API by obvykle měly odvozovat spíše z ControllerBase než z Controller. Controller
odvozuje z ControllerBase a přidává podporu zobrazení. Je tedy určený pro zpracování webových stránek, nikoli požadavků webového rozhraní API. Pokud stejný kontroler musí podporovat zobrazení i webová rozhraní API, odvozujte z Controller
.
Třída ControllerBase
poskytuje mnoho vlastností a metod, které jsou užitečné pro zpracování požadavků HTTP. Například CreatedAtAction vrátí stavový kód 201:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Následující tabulka obsahuje příklady metod v ControllerBase
.
metoda | Notes |
---|---|
BadRequest | Vrátí stavový kód 400. |
NotFound | Vrátí stavový kód 404. |
PhysicalFile | Vrátí soubor. |
TryUpdateModelAsync | Vyvolá vazbu modelu. |
TryValidateModel | Vyvolá ověření modelu. |
Seznam všech dostupných metod a vlastností najdete v tématu ControllerBase.
Atributy
Obor názvů Microsoft.AspNetCore.Mvc poskytuje atributy, které lze použít ke konfiguraci chování kontrolerů webového rozhraní API a metod akcí. Následující příklad používá atributy k určení podporované operace akce HTTP a všech známých stavových kódů HTTP, které by mohly být vráceny:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Tady je několik dalších příkladů atributů, které jsou k dispozici.
Atribut | Notes |
---|---|
[Route] |
Určuje vzor adresy URL pro kontroler nebo akci. |
[Bind] |
Určuje předponu a vlastnosti, které se mají zahrnout pro vazbu modelu. |
[HttpGet] |
Identifikuje akci, která podporuje operaci akce HTTP GET. |
[Consumes] |
Určuje datové typy, které akce přijímá. |
[Produces] |
Určuje datové typy, které akce vrací. |
Seznam, který obsahuje dostupné atributy, najdete v oboru názvů Microsoft.AspNetCore.Mvc.
Atribut ApiController
Atribut [ApiController]
lze použít u třídy kontroleru k povolení následujícího názorného chování specifického pro rozhraní API:
- Požadavek na směrování atributů
- Automatické odpovědi HTTP 400
- Odvozování parametrů zdroje vazby
- Odvozování požadavků multipart/form-data
- Podrobnosti o problému se stavovými kódy chyb
Atribut u konkrétních kontrolerů
Atribut [ApiController]
lze použít pro konkrétní kontrolery, jako v následujícím příkladu ze šablony projektu:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Atribut u několika kontrolerů
Jedním z přístupů k použití atributu ve více než jednom kontroleru je vytvoření vlastní základní třídy kontroleru, která je označená atributem [ApiController]
. Následující příklad ukazuje vlastní základní třídu a kontroler, který se z ní odvozuje:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
Atribut u sestavení
Atribut [ApiController]
lze použít pro sestavení. Při použití atributu [ApiController]
u sestavení je pro všechny kontrolery v sestavení použitý atribut [ApiController]
. Pro jednotlivé ovladače neexistuje možnost výslovně nesouhlasit. Pro soubor Program.cs
použijte atribut na úrovni sestavení:
using Microsoft.AspNetCore.Mvc;
[assembly: ApiController]
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Požadavek na směrování atributů
Atribut [ApiController]
zajišťuje směrování atributů jako požadavek. Příklad:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Akce jsou nepřístupné prostřednictvím konvenčních tras definovaných pomocí UseEndpoints
, UseMvc nebo UseMvcWithDefaultRoute.
Automatické odpovědi HTTP 400
Atribut [ApiController]
zajistí, že chyby ověření modelu automaticky aktivují odpověď HTTP 400. V důsledku toho je následující kód v metodě akce nepotřebný:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC k provedení předchozí kontroly používá filtr akcí ModelStateInvalidFilter.
Výchozí odpověď BadRequest
Výchozí typ odpovědi pro odpověď HTTP 400 je ValidationProblemDetails. Následující text odpovědi je příkladem serializovaného typu:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|7fb5e16a-4c8f23bbfc974667.",
"errors": {
"": [
"A non-empty request body is required."
]
}
}
Typ ValidationProblemDetails
:
- Poskytuje strojově čitelný formát pro určení chyb v odpovědích webového rozhraní API.
- Splňuje specifikaci RFC 7807.
Pokud chcete, aby automatické a vlastní odpovědi byly konzistentní, volejte metodu ValidationProblem místo BadRequest. ValidationProblem
vrátí objekt ValidationProblemDetails i automatickou odpověď.
Protokolování automatických odpovědí 400
Pokud chcete protokolovat automatické odpovědi 400, nastavte vlastnost delegáta InvalidModelStateResponseFactory tak, aby prováděla vlastní zpracování. Ve výchozím nastavení InvalidModelStateResponseFactory
využívá ProblemDetailsFactory k vytvoření instance ValidationProblemDetails.
Následující příklad ukazuje, jak načíst instanci ILogger<TCategoryName> pro protokolování informací o automatické odpovědi 400:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
// To preserve the default behavior, capture the original delegate to call later.
var builtInFactory = options.InvalidModelStateResponseFactory;
options.InvalidModelStateResponseFactory = context =>
{
var logger = context.HttpContext.RequestServices
.GetRequiredService<ILogger<Program>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a ValidationProblemDetails
// response.
// To produce a custom response, return a different implementation of
// IActionResult instead.
return builtInFactory(context);
};
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Zákaz automatické odpovědi 400
Chcete-li zakázat automatické chování 400, nastavte vlastnost SuppressModelStateInvalidFilter na true
. Přidejte následující zvýrazněný kód:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Odvozování parametrů zdroje vazby
Atribut zdroje vazby definuje umístění, ve kterém se nachází hodnota parametru akce. Existují následující zdrojové atributy vazby:
Atribut | Zdroj vazby |
---|---|
[FromBody] |
Text požadavku |
[FromForm] |
Formulářová data v textu požadavku |
[FromHeader] |
Hlavička požadavku |
[FromQuery] |
Parametr řetězce dotazu požadavku |
[FromRoute] |
Směrování dat z aktuálního požadavku |
[FromServices] |
Služba požadavku vložená jako parametr akce |
[AsParameters] |
Parametry metody |
Upozorňující
Nepoužívejte [FromRoute]
, pokud hodnoty mohou obsahovat %2f
(to znamená /
). %2f
se nepřevedou na /
. Pokud hodnota může obsahovat %2f
, použijte [FromQuery]
.
Bez atributu [ApiController]
nebo atributů zdroje vazby, jako je [FromQuery]
, se modul runtime ASP.NET Core pokusí použít komplexní objektový vazač modelů. Komplexní objektový vazač modelů načítá data z poskytovatelů hodnot v definovaném pořadí.
V následujícím příkladu atribut [FromQuery]
označuje, že hodnota parametru discontinuedOnly
je poskytnuta v řetězci dotazu adresy URL požadavku:
[HttpGet]
public ActionResult<List<Product>> Get(
[FromQuery] bool discontinuedOnly = false)
{
List<Product> products = null;
if (discontinuedOnly)
{
products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
}
else
{
products = _productsInMemoryStore;
}
return products;
}
Atribut [ApiController]
používá odvozená pravidla pro výchozí zdroje dat parametrů akce. Tato pravidla vám ušetří nutnost ručně identifikovat zdroje vazeb použitím atributů na parametry akce. Odvozená pravidla zdroje vazby se chovají takto:
[FromServices]
se odvozuje pro parametry komplexního typu, které jsou registrované v kontejneru injektáže závislostí.[FromBody]
se odvozuje pro parametry komplexního typu, které nejsou registrované v kontejneru injektáže závislostí. Výjimkou pro odvozené pravidlo[FromBody]
je libovolný komplexní předdefinovaný typ se speciálním významem, jako je IFormCollection a CancellationToken. Kód odvození zdroje vazby tyto speciální typy ignoruje.[FromForm]
se odvozuje pro parametry typu IFormFile a IFormFileCollection. Neodvozuje se pro žádné jednoduché nebo uživatelsky definované typy.[FromRoute]
se odvozuje pro libovolný název parametru akce odpovídající parametru v šabloně trasy. Pokud parametru akce odpovídá více než jedna trasa, za[FromRoute]
se považuje libovolná hodnota trasy.[FromQuery]
se odvozuje pro všechny ostatní parametry.
Poznámky k odvozování FromBody
[FromBody]
se neodvozuje pro jednoduché typy, jako je string
nebo int
. Proto by se atribut [FromBody]
měl pro jednoduché typy používat, pokud je tato funkce potřebná.
Pokud má akce více parametrů vázaných z textu požadavku, vyvolá se výjimka. Například všechny následující podpisy metody akce způsobují výjimku:
[FromBody]
se odvozuje v obou případech, protože jde o komplexní typy.[HttpPost] public IActionResult Action1(Product product, Order order)
Atribut
[FromBody]
v jednom případě, odvozený v druhém, protože jde o komplexní typ.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Atribut
[FromBody]
v obou případech.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Poznámky k odvozování FromServices
Vazby parametrů sváže parametry prostřednictvím injektáže závislostí, když je typ nakonfigurován jako služba. To znamená, že není nutné explicitně použít [FromServices]
atribut na parametr. V následujícím kódu vrátí obě akce čas:
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
public ActionResult GetWithAttribute([FromServices] IDateTime dateTime)
=> Ok(dateTime.Now);
[Route("noAttribute")]
public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);
}
Vevýjimečných Není běžné mít typ v DI a jako argument v akci kontroleru rozhraní API.
Pokud chcete zakázat odvozování [FromServices]
pro jeden parametr akce, použijte u parametru požadovaný atribut zdroje vazby. Použijte například atribut [FromBody]
pro parametr akce, který by měl být vázaný z textu požadavku.
Pokud chcete zakázat [FromServices]
odvozování globálně, nastavte DisableImplicitFromServicesParameters na true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSingleton<IDateTime, SystemDateTime>();
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
options.DisableImplicitFromServicesParameters = true;
});
var app = builder.Build();
app.MapControllers();
app.Run();
Typy se kontrolují při spuštění aplikace s IServiceProviderIsService cílem určit, jestli argument v akci kontroleru rozhraní API pochází z DI nebo z jiných zdrojů.
Mechanismus odvození zdroje vazby parametrů akce kontroleru rozhraní API používá následující pravidla:
- Dříve zadaný
BindingInfo.BindingSource
text se nikdy nepřepíše. - Je přiřazen
BindingSource.Services
parametr komplexního typu zaregistrovaný v kontejneru DI . - Je přiřazen
BindingSource.Body
parametr komplexního typu, který není registrován v kontejneru DI . - Parametr s názvem, který se zobrazí jako hodnota trasy v jakékoli šabloně trasy, je přiřazen
BindingSource.Path
. - Všechny ostatní parametry jsou
BindingSource.Query
.
Zákaz odvozených pravidel
Pokud chcete zakázat odvozování zdroje vazby, nastavte SuppressInferBindingSourcesForParameters na true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Odvozování požadavků multipart/form-data
Atribut [ApiController]
použije odvozené pravidlo pro parametry akce typu IFormFile a IFormFileCollection. Typ obsahu požadavku multipart/form-data
je odvozený pro tyto typy.
Pokud chcete zakázat výchozí chování, nastavte vlastnost SuppressConsumesConstraintForFormFileParameters na true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Podrobnosti o problému se stavovými kódy chyb
MVC transformuje výsledek chyby (výsledek se stavovým kódem 400 nebo vyšší) na výsledek s typem ProblemDetails. Typ ProblemDetails
je založený na specifikaci RFC 7807 pro poskytování strojově čitelných podrobností o chybě v odpovědi HTTP.
Zvažte použití následujícího kódu v akci kontroleru:
if (pet == null)
{
return NotFound();
}
Metoda NotFound
vytvoří stavový kód HTTP 404 s textem ProblemDetails
. Příklad:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Zákaz odpovědi ProblemDetails
Automatické vytvoření ProblemDetails
pro stavové kódy kódů chyb je zakázáno, pokud je vlastnost SuppressMapClientErrors nastavená na true
. Přidejte následující kód:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Definování podporovaných typů obsahu požadavku s atributem [Consumes]
Akce ve výchozím nastavení podporuje všechny dostupné typy obsahu požadavku. Pokud je například aplikace nakonfigurovaná tak, aby podporovala vstupní formátovací moduly JSON i XML, akce podporuje více typů obsahu, včetně application/json
a application/xml
.
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavku. Atribut [Consumes]
použijte u akce nebo kontroleru s určením jednoho nebo několika typů obsahu:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Akce CreateProduct
v předchozím kódu určuje typ obsahu application/xml
. Požadavky směrované na tuto akci musí zadat hlavičku Content-Type
typu application/xml
. Požadavky, které neurčují hlavičku Content-Type
typu application/xml
, vedou k odpovědi 415 Nepodporovaný typ média.
Atribut [Consumes]
také akci umožňuje ovlivnit její výběr na základě typu obsahu příchozího požadavku, a to použitím omezení typu. Představte si následující příklad:
[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
[HttpPost]
[Consumes("application/json")]
public IActionResult PostJson(IEnumerable<int> values) =>
Ok(new { Consumes = "application/json", Values = values });
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}
V předchozím kódu je třída ConsumesController
nakonfigurovaná tak, aby zpracovávala požadavky odeslané na adresu URL https://localhost:5001/api/Consumes
. Obě akce kontroleru, PostJson
i PostForm
, zpracovávají požadavky POST se stejnou adresou URL. Bez atributu [Consumes]
aplikujícího omezení výjimky se vyvolá výjimka nejednoznačné shody.
Atribut [Consumes]
se použije u obou akcí. Akce PostJson
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/json
. Akce PostForm
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/x-www-form-urlencoded
.
Další materiály
- Zobrazení nebo stažení vzorového kódu (postup stahování).
- Návratové typy akcí kontroleru ve webovém rozhraní API ASP.NET Core
- Zpracování chyb ve webových rozhraních API založených na řadiči jádra ASP.NET
- Vlastní formátovací moduly ve webových rozhraních API ASP.NET Core
- Formátování dat odpovědí ve webovém rozhraní API ASP.NET Core
- Dokumentace k webovému rozhraní API ASP.NET Core s využitím Swaggeru/OpenAPI
- Směrování na akce kontroleru v ASP.NET Core
- Použití tunelového propojení portů v sadě Visual Studio k ladění webových rozhraní API
- Vytvoření webového rozhraní API pomocí ASP.NET Core
ASP.NET Core podporuje vytváření webových rozhraní API pomocí kontrolerů nebo minimálních rozhraní API. Kontrolery ve webovém rozhraní API jsou třídy, které odvozují z ControllerBase. Tento článek ukazuje, jak kontrolery využívat ke zpracování požadavků webového rozhraní API. Informace o vytváření webových rozhraní API bez kontrolerů najdete v kurzu : Vytvoření minimálního rozhraní API s ASP.NET Core.
Třída ControllerBase
Webové rozhraní API založené na kontroleru se skládá z jedné nebo několika tříd kontrolerů, které odvozují z ControllerBase. Šablona projektu webového rozhraní API poskytuje počáteční kontroler:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Kontrolery webového rozhraní API by obvykle měly odvozovat spíše z ControllerBase než z Controller. Controller
odvozuje z ControllerBase a přidává podporu zobrazení. Je tedy určený pro zpracování webových stránek, nikoli požadavků webového rozhraní API. Pokud stejný kontroler musí podporovat zobrazení i webová rozhraní API, odvozujte z Controller
.
Třída ControllerBase
poskytuje mnoho vlastností a metod, které jsou užitečné pro zpracování požadavků HTTP. Například CreatedAtAction vrátí stavový kód 201:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Následující tabulka obsahuje příklady metod v ControllerBase
.
metoda | Notes |
---|---|
BadRequest | Vrátí stavový kód 400. |
NotFound | Vrátí stavový kód 404. |
PhysicalFile | Vrátí soubor. |
TryUpdateModelAsync | Vyvolá vazbu modelu. |
TryValidateModel | Vyvolá ověření modelu. |
Seznam všech dostupných metod a vlastností najdete v tématu ControllerBase.
Atributy
Obor názvů Microsoft.AspNetCore.Mvc poskytuje atributy, které lze použít ke konfiguraci chování kontrolerů webového rozhraní API a metod akcí. Následující příklad používá atributy k určení podporované operace akce HTTP a všech známých stavových kódů HTTP, které by mohly být vráceny:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Tady je několik dalších příkladů atributů, které jsou k dispozici.
Atribut | Notes |
---|---|
[Route] |
Určuje vzor adresy URL pro kontroler nebo akci. |
[Bind] |
Určuje předponu a vlastnosti, které se mají zahrnout pro vazbu modelu. |
[HttpGet] |
Identifikuje akci, která podporuje operaci akce HTTP GET. |
[Consumes] |
Určuje datové typy, které akce přijímá. |
[Produces] |
Určuje datové typy, které akce vrací. |
Seznam, který obsahuje dostupné atributy, najdete v oboru názvů Microsoft.AspNetCore.Mvc.
Atribut ApiController
Atribut [ApiController]
lze použít u třídy kontroleru k povolení následujícího názorného chování specifického pro rozhraní API:
- Požadavek na směrování atributů
- Automatické odpovědi HTTP 400
- Odvozování parametrů zdroje vazby
- Odvozování požadavků multipart/form-data
- Podrobnosti o problému se stavovými kódy chyb
Atribut u konkrétních kontrolerů
Atribut [ApiController]
lze použít pro konkrétní kontrolery, jako v následujícím příkladu ze šablony projektu:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Atribut u několika kontrolerů
Jedním z přístupů k použití atributu ve více než jednom kontroleru je vytvoření vlastní základní třídy kontroleru, která je označená atributem [ApiController]
. Následující příklad ukazuje vlastní základní třídu a kontroler, který se z ní odvozuje:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
Atribut u sestavení
Atribut [ApiController]
lze použít pro sestavení. Při použití atributu [ApiController]
u sestavení je pro všechny kontrolery v sestavení použitý atribut [ApiController]
. Pro jednotlivé ovladače neexistuje možnost výslovně nesouhlasit. Pro soubor Program.cs
použijte atribut na úrovni sestavení:
using Microsoft.AspNetCore.Mvc;
[assembly: ApiController]
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Požadavek na směrování atributů
Atribut [ApiController]
zajišťuje směrování atributů jako požadavek. Příklad:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Akce jsou nepřístupné prostřednictvím konvenčních tras definovaných pomocí UseEndpoints
, UseMvc nebo UseMvcWithDefaultRoute.
Automatické odpovědi HTTP 400
Atribut [ApiController]
zajistí, že chyby ověření modelu automaticky aktivují odpověď HTTP 400. V důsledku toho je následující kód v metodě akce nepotřebný:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC k provedení předchozí kontroly používá filtr akcí ModelStateInvalidFilter.
Výchozí odpověď BadRequest
Následující text odpovědi je příkladem serializovaného typu:
{
"": [
"A non-empty request body is required."
]
}
Výchozí typ odpovědi pro odpověď HTTP 400 je ValidationProblemDetails. Následující text odpovědi je příkladem serializovaného typu:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|7fb5e16a-4c8f23bbfc974667.",
"errors": {
"": [
"A non-empty request body is required."
]
}
}
Typ ValidationProblemDetails
:
- Poskytuje strojově čitelný formát pro určení chyb v odpovědích webového rozhraní API.
- Splňuje specifikaci RFC 7807.
Pokud chcete, aby automatické a vlastní odpovědi byly konzistentní, volejte metodu ValidationProblem místo BadRequest. ValidationProblem
vrátí objekt ValidationProblemDetails i automatickou odpověď.
Protokolování automatických odpovědí 400
Pokud chcete protokolovat automatické odpovědi 400, nastavte vlastnost delegáta InvalidModelStateResponseFactory tak, aby prováděla vlastní zpracování. Ve výchozím nastavení InvalidModelStateResponseFactory
využívá ProblemDetailsFactory k vytvoření instance ValidationProblemDetails.
Následující příklad ukazuje, jak načíst instanci ILogger<TCategoryName> pro protokolování informací o automatické odpovědi 400:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
// To preserve the default behavior, capture the original delegate to call later.
var builtInFactory = options.InvalidModelStateResponseFactory;
options.InvalidModelStateResponseFactory = context =>
{
var logger = context.HttpContext.RequestServices
.GetRequiredService<ILogger<Program>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a ValidationProblemDetails
// response.
// To produce a custom response, return a different implementation of
// IActionResult instead.
return builtInFactory(context);
};
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Zákaz automatické odpovědi 400
Chcete-li zakázat automatické chování 400, nastavte vlastnost SuppressModelStateInvalidFilter na true
. Přidejte následující zvýrazněný kód:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Odvozování parametrů zdroje vazby
Atribut zdroje vazby definuje umístění, ve kterém se nachází hodnota parametru akce. Existují následující zdrojové atributy vazby:
Atribut | Zdroj vazby |
---|---|
[FromBody] |
Text požadavku |
[FromForm] |
Formulářová data v textu požadavku |
[FromHeader] |
Hlavička požadavku |
[FromQuery] |
Parametr řetězce dotazu požadavku |
[FromRoute] |
Směrování dat z aktuálního požadavku |
[FromServices] |
Služba požadavku vložená jako parametr akce |
Upozorňující
Nepoužívejte [FromRoute]
, pokud hodnoty mohou obsahovat %2f
(to znamená /
). %2f
se nepřevedou na /
. Pokud hodnota může obsahovat %2f
, použijte [FromQuery]
.
Bez atributu [ApiController]
nebo atributů zdroje vazby, jako je [FromQuery]
, se modul runtime ASP.NET Core pokusí použít komplexní objektový vazač modelů. Komplexní objektový vazač modelů načítá data z poskytovatelů hodnot v definovaném pořadí.
V následujícím příkladu atribut [FromQuery]
označuje, že hodnota parametru discontinuedOnly
je poskytnuta v řetězci dotazu adresy URL požadavku:
[HttpGet]
public ActionResult<List<Product>> Get(
[FromQuery] bool discontinuedOnly = false)
{
List<Product> products = null;
if (discontinuedOnly)
{
products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
}
else
{
products = _productsInMemoryStore;
}
return products;
}
Atribut [ApiController]
používá odvozená pravidla pro výchozí zdroje dat parametrů akce. Tato pravidla vám ušetří nutnost ručně identifikovat zdroje vazeb použitím atributů na parametry akce. Odvozená pravidla zdroje vazby se chovají takto:
[FromBody]
se odvozuje pro parametry komplexního typu, které nejsou registrované v kontejneru injektáže závislostí. Výjimkou pro odvozené pravidlo[FromBody]
je libovolný komplexní předdefinovaný typ se speciálním významem, jako je IFormCollection a CancellationToken. Kód odvození zdroje vazby tyto speciální typy ignoruje.[FromForm]
se odvozuje pro parametry typu IFormFile a IFormFileCollection. Neodvozuje se pro žádné jednoduché nebo uživatelsky definované typy.[FromRoute]
se odvozuje pro libovolný název parametru akce odpovídající parametru v šabloně trasy. Pokud parametru akce odpovídá více než jedna trasa, za[FromRoute]
se považuje libovolná hodnota trasy.[FromQuery]
se odvozuje pro všechny ostatní parametry.
Poznámky k odvozování FromBody
[FromBody]
se neodvozuje pro jednoduché typy, jako je string
nebo int
. Proto by se atribut [FromBody]
měl pro jednoduché typy používat, pokud je tato funkce potřebná.
Pokud má akce více parametrů vázaných z textu požadavku, vyvolá se výjimka. Například všechny následující podpisy metody akce způsobují výjimku:
[FromBody]
se odvozuje v obou případech, protože jde o komplexní typy.[HttpPost] public IActionResult Action1(Product product, Order order)
Atribut
[FromBody]
v jednom případě, odvozený v druhém, protože jde o komplexní typ.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Atribut
[FromBody]
v obou případech.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Zákaz odvozených pravidel
Pokud chcete zakázat odvozování zdroje vazby, nastavte SuppressInferBindingSourcesForParameters na true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Odvozování požadavků multipart/form-data
Atribut [ApiController]
použije odvozené pravidlo pro parametry akce typu IFormFile a IFormFileCollection. Typ obsahu požadavku multipart/form-data
je odvozený pro tyto typy.
Pokud chcete zakázat výchozí chování, nastavte vlastnost SuppressConsumesConstraintForFormFileParameters na true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Podrobnosti o problému se stavovými kódy chyb
MVC transformuje výsledek chyby (výsledek se stavovým kódem 400 nebo vyšší) na výsledek s typem ProblemDetails. Typ ProblemDetails
je založený na specifikaci RFC 7807 pro poskytování strojově čitelných podrobností o chybě v odpovědi HTTP.
Zvažte použití následujícího kódu v akci kontroleru:
if (pet == null)
{
return NotFound();
}
Metoda NotFound
vytvoří stavový kód HTTP 404 s textem ProblemDetails
. Příklad:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Zákaz odpovědi ProblemDetails
Automatické vytvoření ProblemDetails
pro stavové kódy kódů chyb je zakázáno, pokud je vlastnost SuppressMapClientErrors nastavená na true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Definování podporovaných typů obsahu požadavku s atributem [Consumes]
Akce ve výchozím nastavení podporuje všechny dostupné typy obsahu požadavku. Pokud je například aplikace nakonfigurovaná tak, aby podporovala vstupní formátovací moduly JSON i XML, akce podporuje více typů obsahu, včetně application/json
a application/xml
.
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavku. Atribut [Consumes]
použijte u akce nebo kontroleru s určením jednoho nebo několika typů obsahu:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Akce CreateProduct
v předchozím kódu určuje typ obsahu application/xml
. Požadavky směrované na tuto akci musí zadat hlavičku Content-Type
typu application/xml
. Požadavky, které neurčují hlavičku Content-Type
typu application/xml
, vedou k odpovědi 415 Nepodporovaný typ média.
Atribut [Consumes]
také akci umožňuje ovlivnit její výběr na základě typu obsahu příchozího požadavku, a to použitím omezení typu. Představte si následující příklad:
[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
[HttpPost]
[Consumes("application/json")]
public IActionResult PostJson(IEnumerable<int> values) =>
Ok(new { Consumes = "application/json", Values = values });
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}
V předchozím kódu je třída ConsumesController
nakonfigurovaná tak, aby zpracovávala požadavky odeslané na adresu URL https://localhost:5001/api/Consumes
. Obě akce kontroleru, PostJson
i PostForm
, zpracovávají požadavky POST se stejnou adresou URL. Bez atributu [Consumes]
aplikujícího omezení výjimky se vyvolá výjimka nejednoznačné shody.
Atribut [Consumes]
se použije u obou akcí. Akce PostJson
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/json
. Akce PostForm
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/x-www-form-urlencoded
.
Další materiály
- Zobrazení nebo stažení vzorového kódu (postup stahování).
- Návratové typy akcí kontroleru ve webovém rozhraní API ASP.NET Core
- Zpracování chyb ve webových rozhraních API založených na řadiči jádra ASP.NET
- Vlastní formátovací moduly ve webových rozhraních API ASP.NET Core
- Formátování dat odpovědí ve webovém rozhraní API ASP.NET Core
- Dokumentace k webovému rozhraní API ASP.NET Core s využitím Swaggeru/OpenAPI
- Směrování na akce kontroleru v ASP.NET Core
- Použití tunelového propojení portů v sadě Visual Studio k ladění webových rozhraní API
- Vytvoření webového rozhraní API pomocí ASP.NET Core
ASP.NET Core podporuje vytváření služeb RESTful v jazyce C# (služby RESTful se označují také jako webová rozhraní API). Webové rozhraní API používá ke zpracování požadavků kontrolery. Kontrolery ve webovém rozhraní API jsou třídy, které odvozují z ControllerBase
. Tento článek ukazuje, jak kontrolery využívat ke zpracování požadavků webového rozhraní API.
Zobrazení nebo stažení vzorového kódu (postup stahování).
Třída ControllerBase
Webové rozhraní API se skládá z jedné nebo několika tříd kontrolerů, které odvozují z ControllerBase. Šablona projektu webového rozhraní API poskytuje počáteční kontroler:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Nevytvářejte kontroler webového rozhraní API odvozením z třídy Controller. Controller
odvozuje z ControllerBase
a přidává podporu zobrazení. Je tedy určený pro zpracování webových stránek, nikoli požadavků webového rozhraní API. Toto pravidlo má výjimku: Pokud plánujete použít stejný kontroler pro zobrazení i webová rozhraní API, odvozujte ho z třídy Controller
.
Třída ControllerBase
poskytuje mnoho vlastností a metod, které jsou užitečné pro zpracování požadavků HTTP. Například ControllerBase.CreatedAtAction
vrátí stavový kód 201:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Tady je několik dalších příkladů metod, které ControllerBase
poskytuje.
metoda | Notes |
---|---|
BadRequest | Vrátí stavový kód 400. |
NotFound | Vrátí stavový kód 404. |
PhysicalFile | Vrátí soubor. |
TryUpdateModelAsync | Vyvolá vazbu modelu. |
TryValidateModel | Vyvolá ověření modelu. |
Seznam všech dostupných metod a vlastností najdete v tématu ControllerBase.
Atributy
Obor názvů Microsoft.AspNetCore.Mvc poskytuje atributy, které lze použít ke konfiguraci chování kontrolerů webového rozhraní API a metod akcí. Následující příklad používá atributy k určení podporované operace akce HTTP a všech známých stavových kódů HTTP, které by mohly být vráceny:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Tady je několik dalších příkladů atributů, které jsou k dispozici.
Atribut | Notes |
---|---|
[Route] |
Určuje vzor adresy URL pro kontroler nebo akci. |
[Bind] |
Určuje předponu a vlastnosti, které se mají zahrnout pro vazbu modelu. |
[HttpGet] |
Identifikuje akci, která podporuje operaci akce HTTP GET. |
[Consumes] |
Určuje datové typy, které akce přijímá. |
[Produces] |
Určuje datové typy, které akce vrací. |
Seznam, který obsahuje dostupné atributy, najdete v oboru názvů Microsoft.AspNetCore.Mvc.
Atribut ApiController
Atribut [ApiController]
lze použít u třídy kontroleru k povolení následujícího názorného chování specifického pro rozhraní API:
- Požadavek na směrování atributů
- Automatické odpovědi HTTP 400
- Odvozování parametrů zdroje vazby
- Odvozování požadavků multipart/form-data
- Podrobnosti o problému se stavovými kódy chyb
Atribut u konkrétních kontrolerů
Atribut [ApiController]
lze použít pro konkrétní kontrolery, jako v následujícím příkladu ze šablony projektu:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Atribut u několika kontrolerů
Jedním z přístupů k použití atributu ve více než jednom kontroleru je vytvoření vlastní základní třídy kontroleru, která je označená atributem [ApiController]
. Následující příklad ukazuje vlastní základní třídu a kontroler, který se z ní odvozuje:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
Atribut u sestavení
Atribut [ApiController]
lze použít pro sestavení. Anotace tímto způsobem aplikuje chování webového rozhraní API na všechny kontrolery v sestavení. Pro jednotlivé ovladače neexistuje možnost výslovně nesouhlasit. Použijte atribut na úrovni sestavení na deklaraci oboru názvů u třídy Startup
:
[assembly: ApiController]
namespace WebApiSample
{
public class Startup
{
...
}
}
Požadavek na směrování atributů
Atribut [ApiController]
zajišťuje směrování atributů jako požadavek. Příklad:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Akce jsou nepřístupné prostřednictvím konvenčních tras definovaných pomocí UseEndpoints
, UseMvc nebo UseMvcWithDefaultRoute v Startup.Configure
.
Automatické odpovědi HTTP 400
Atribut [ApiController]
zajistí, že chyby ověření modelu automaticky aktivují odpověď HTTP 400. V důsledku toho je následující kód v metodě akce nepotřebný:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC k provedení předchozí kontroly používá filtr akcí ModelStateInvalidFilter.
Výchozí odpověď BadRequest
Následující text požadavku je příkladem serializovaného typu:
{
"": [
"A non-empty request body is required."
]
}
Výchozí typ odpovědi pro odpověď HTTP 400 je ValidationProblemDetails. Následující text požadavku je příkladem serializovaného typu:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|7fb5e16a-4c8f23bbfc974667.",
"errors": {
"": [
"A non-empty request body is required."
]
}
}
Typ ValidationProblemDetails
:
- Poskytuje strojově čitelný formát pro určení chyb v odpovědích webového rozhraní API.
- Splňuje specifikaci RFC 7807.
Pokud chcete, aby automatické a vlastní odpovědi byly konzistentní, volejte metodu ValidationProblem místo BadRequest. ValidationProblem
vrátí objekt ValidationProblemDetails i automatickou odpověď.
Protokolování automatických odpovědí 400
Pokud chcete protokolovat automatické odpovědi 400, nastavte vlastnost delegáta InvalidModelStateResponseFactory tak, aby prováděla vlastní zpracování v Startup.ConfigureServices
. Ve výchozím nastavení InvalidModelStateResponseFactory
využívá ProblemDetailsFactory k vytvoření instance ValidationProblemDetails.
Následující příklad ukazuje, jak načíst instanci ILogger<TCategoryName> pro protokolování informací o automatické odpovědi 400:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
// To preserve the default behavior, capture the original delegate to call later.
var builtInFactory = options.InvalidModelStateResponseFactory;
options.InvalidModelStateResponseFactory = context =>
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Startup>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a ValidationProblemDetails response.
// To produce a custom response, return a different implementation of IActionResult instead.
return builtInFactory(context);
};
});
Zákaz automatické odpovědi 400
Chcete-li zakázat automatické chování 400, nastavte vlastnost SuppressModelStateInvalidFilter na true
. Přidejte následující zvýrazněný kód v Startup.ConfigureServices
:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
});
Odvozování parametrů zdroje vazby
Atribut zdroje vazby definuje umístění, ve kterém se nachází hodnota parametru akce. Existují následující zdrojové atributy vazby:
Atribut | Zdroj vazby |
---|---|
[FromBody] |
Text požadavku |
[FromForm] |
Formulářová data v textu požadavku |
[FromHeader] |
Hlavička požadavku |
[FromQuery] |
Parametr řetězce dotazu požadavku |
[FromRoute] |
Směrování dat z aktuálního požadavku |
[FromServices] |
Služba požadavku vložená jako parametr akce |
Upozorňující
Nepoužívejte [FromRoute]
, pokud hodnoty mohou obsahovat %2f
(to znamená /
). %2f
se nepřevedou na /
. Pokud hodnota může obsahovat %2f
, použijte [FromQuery]
.
Bez atributu [ApiController]
nebo atributů zdroje vazby, jako je [FromQuery]
, se modul runtime ASP.NET Core pokusí použít komplexní objektový vazač modelů. Komplexní objektový vazač modelů načítá data z poskytovatelů hodnot v definovaném pořadí.
V následujícím příkladu atribut [FromQuery]
označuje, že hodnota parametru discontinuedOnly
je poskytnuta v řetězci dotazu adresy URL požadavku:
[HttpGet]
public ActionResult<List<Product>> Get(
[FromQuery] bool discontinuedOnly = false)
{
List<Product> products = null;
if (discontinuedOnly)
{
products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
}
else
{
products = _productsInMemoryStore;
}
return products;
}
Atribut [ApiController]
používá odvozená pravidla pro výchozí zdroje dat parametrů akce. Tato pravidla vám ušetří nutnost ručně identifikovat zdroje vazeb použitím atributů na parametry akce. Odvozená pravidla zdroje vazby se chovají takto:
[FromBody]
se odvozuje pro parametry komplexního typu. Výjimkou pro odvozené pravidlo[FromBody]
je libovolný komplexní předdefinovaný typ se speciálním významem, jako je IFormCollection a CancellationToken. Kód odvození zdroje vazby tyto speciální typy ignoruje.[FromForm]
se odvozuje pro parametry typu IFormFile a IFormFileCollection. Neodvozuje se pro žádné jednoduché nebo uživatelsky definované typy.[FromRoute]
se odvozuje pro libovolný název parametru akce odpovídající parametru v šabloně trasy. Pokud parametru akce odpovídá více než jedna trasa, za[FromRoute]
se považuje libovolná hodnota trasy.[FromQuery]
se odvozuje pro všechny ostatní parametry.
Poznámky k odvozování FromBody
[FromBody]
se neodvozuje pro jednoduché typy, jako je string
nebo int
. Proto by se atribut [FromBody]
měl pro jednoduché typy používat, pokud je tato funkce potřebná.
Pokud má akce více parametrů vázaných z textu požadavku, vyvolá se výjimka. Například všechny následující podpisy metody akce způsobují výjimku:
[FromBody]
se odvozuje v obou případech, protože jde o komplexní typy.[HttpPost] public IActionResult Action1(Product product, Order order)
Atribut
[FromBody]
v jednom případě, odvozený v druhém, protože jde o komplexní typ.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Atribut
[FromBody]
v obou případech.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Zákaz odvozených pravidel
Pokud chcete zakázat odvozování zdroje vazby, nastavte SuppressInferBindingSourcesForParameters na true
. V souboru Startup.ConfigureServices
přidejte následující kód:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
});
Odvozování požadavků multipart/form-data
Atribut [ApiController]
použije odvozené pravidlo pro parametry akce typu IFormFile a IFormFileCollection. Typ obsahu požadavku multipart/form-data
je odvozený pro tyto typy.
Pokud chcete zakázat výchozí chování, nastavte vlastnost SuppressConsumesConstraintForFormFileParameters na true
v Startup.ConfigureServices
:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
});
Podrobnosti o problému se stavovými kódy chyb
MVC transformuje výsledek chyby (výsledek se stavovým kódem 400 nebo vyšší) na výsledek s typem ProblemDetails. Typ ProblemDetails
je založený na specifikaci RFC 7807 pro poskytování strojově čitelných podrobností o chybě v odpovědi HTTP.
Zvažte použití následujícího kódu v akci kontroleru:
if (pet == null)
{
return NotFound();
}
Metoda NotFound
vytvoří stavový kód HTTP 404 s textem ProblemDetails
. Příklad:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Zákaz odpovědi ProblemDetails
Automatické vytvoření ProblemDetails
pro stavové kódy kódů chyb je zakázáno, pokud je vlastnost SuppressMapClientErrors nastavená na true
. V souboru Startup.ConfigureServices
přidejte následující kód:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
});
Definování podporovaných typů obsahu požadavku s atributem [Consumes]
Akce ve výchozím nastavení podporuje všechny dostupné typy obsahu požadavku. Pokud je například aplikace nakonfigurovaná tak, aby podporovala vstupní formátovací moduly JSON i XML, akce podporuje více typů obsahu, včetně application/json
a application/xml
.
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavku. Atribut [Consumes]
použijte u akce nebo kontroleru s určením jednoho nebo několika typů obsahu:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Akce CreateProduct
v předchozím kódu určuje typ obsahu application/xml
. Požadavky směrované na tuto akci musí zadat hlavičku Content-Type
typu application/xml
. Požadavky, které neurčují hlavičku Content-Type
typu application/xml
, vedou k odpovědi 415 Nepodporovaný typ média.
Atribut [Consumes]
také akci umožňuje ovlivnit její výběr na základě typu obsahu příchozího požadavku, a to použitím omezení typu. Představte si následující příklad:
[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
[HttpPost]
[Consumes("application/json")]
public IActionResult PostJson(IEnumerable<int> values) =>
Ok(new { Consumes = "application/json", Values = values });
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}
V předchozím kódu je třída ConsumesController
nakonfigurovaná tak, aby zpracovávala požadavky odeslané na adresu URL https://localhost:5001/api/Consumes
. Obě akce kontroleru, PostJson
i PostForm
, zpracovávají požadavky POST se stejnou adresou URL. Bez atributu [Consumes]
aplikujícího omezení výjimky se vyvolá výjimka nejednoznačné shody.
Atribut [Consumes]
se použije u obou akcí. Akce PostJson
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/json
. Akce PostForm
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/x-www-form-urlencoded
.
Další materiály
- Návratové typy akcí kontroleru ve webovém rozhraní API ASP.NET Core
- Zpracování chyb ve webových rozhraních API založených na řadiči jádra ASP.NET
- Vlastní formátovací moduly ve webových rozhraních API ASP.NET Core
- Formátování dat odpovědí ve webovém rozhraní API ASP.NET Core
- Dokumentace k webovému rozhraní API ASP.NET Core s využitím Swaggeru/OpenAPI
- Směrování na akce kontroleru v ASP.NET Core
- Vytvoření webového rozhraní API pomocí ASP.NET Core
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Nevytvářejte kontroler webového rozhraní API odvozením z třídy Controller. Controller
odvozuje z ControllerBase
a přidává podporu zobrazení. Je tedy určený pro zpracování webových stránek, nikoli požadavků webového rozhraní API. Toto pravidlo má výjimku: Pokud plánujete použít stejný kontroler pro zobrazení i webová rozhraní API, odvozujte ho z třídy Controller
.
Třída ControllerBase
poskytuje mnoho vlastností a metod, které jsou užitečné pro zpracování požadavků HTTP. Například ControllerBase.CreatedAtAction
vrátí stavový kód 201:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Tady je několik dalších příkladů metod, které ControllerBase
poskytuje:
metoda | Notes |
---|---|
BadRequest | Vrátí stavový kód 400. |
NotFound | Vrátí stavový kód 404. |
PhysicalFile | Vrátí soubor. |
TryUpdateModelAsync | Vyvolá vazbu modelu. |
TryValidateModel | Vyvolá ověření modelu. |
Seznam všech dostupných metod a vlastností najdete v tématu ControllerBase.
Atributy
Obor názvů Microsoft.AspNetCore.Mvc poskytuje atributy, které lze použít ke konfiguraci chování kontrolerů webového rozhraní API a metod akcí. Následující příklad používá atributy k určení podporované operace akce HTTP a všech známých stavových kódů HTTP, které by mohly být vráceny:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}
Tady je několik dalších příkladů atributů, které jsou k dispozici:
Atribut | Notes |
---|---|
[Route] |
Určuje vzor adresy URL pro kontroler nebo akci. |
[Bind] |
Určuje předponu a vlastnosti, které se mají zahrnout pro vazbu modelu. |
[HttpGet] |
Identifikuje akci, která podporuje operaci akce HTTP GET. |
[Consumes] |
Určuje datové typy, které akce přijímá. |
[Produces] |
Určuje datové typy, které akce vrací. |
Seznam, který obsahuje dostupné atributy, najdete v oboru názvů Microsoft.AspNetCore.Mvc.
Atribut ApiController
Atribut [ApiController]
lze použít u třídy kontroleru k povolení následujícího názorného chování specifického pro rozhraní API:
- Požadavek na směrování atributů
- Automatické odpovědi HTTP 400
- Odvozování parametrů zdroje vazby
- Odvozování požadavků multipart/form-data
- Podrobnosti o problému se stavovými kódy chyb Funkce Podrobnosti o problému se stavovými kódy chyb vyžaduje verzi kompatibility 2.2 nebo novější. Ostatní funkce vyžadují verzi kompatibility 2.1 nebo novější.
- Požadavek na směrování atributů
- Automatické odpovědi HTTP 400
- Odvozování parametrů zdroje vazby
- Odvozování požadavků multipart/form-data Tyto funkce vyžadují verzi kompatibility 2.1 nebo novější.
Atribut u konkrétních kontrolerů
Atribut [ApiController]
lze použít pro konkrétní kontrolery, jako v následujícím příkladu ze šablony projektu:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Atribut u několika kontrolerů
Jedním z přístupů k použití atributu ve více než jednom kontroleru je vytvoření vlastní základní třídy kontroleru, která je označená atributem [ApiController]
. Následující příklad ukazuje vlastní základní třídu a kontroler, který se z ní odvozuje:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("api/[controller]")]
public class PetsController : MyControllerBase
Atribut u sestavení
Pokud je verze kompatibility nastavená na 2.2 nebo novější, je možné pro sestavení použít atribut [ApiController]
. Anotace tímto způsobem aplikuje chování webového rozhraní API na všechny kontrolery v sestavení. Pro jednotlivé ovladače neexistuje možnost výslovně nesouhlasit. Použijte atribut na úrovni sestavení na deklaraci oboru názvů u třídy Startup
:
[assembly: ApiController]
namespace WebApiSample
{
public class Startup
{
...
}
}
Požadavek na směrování atributů
Atribut [ApiController]
zajišťuje směrování atributů jako požadavek. Příklad:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Akce jsou nepřístupné prostřednictvím konvenčních tras definovaných pomocí UseMvc nebo UseMvcWithDefaultRoute v Startup.Configure
.
Automatické odpovědi HTTP 400
Atribut [ApiController]
zajistí, že chyby ověření modelu automaticky aktivují odpověď HTTP 400. V důsledku toho je následující kód v metodě akce nepotřebný:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC k provedení předchozí kontroly používá filtr akcí ModelStateInvalidFilter.
Výchozí odpověď BadRequest
Při použití verze kompatibility 2.1 je pro odpověď HTTP 400 výchozím typem odpovědi SerializableError. Následující text požadavku je příkladem serializovaného typu:
{
"": [
"A non-empty request body is required."
]
}
Při použití verze kompatibility 2.2 nebo novější je pro odpověď HTTP 400 výchozím typem odpovědi ValidationProblemDetails. Následující text požadavku je příkladem serializovaného typu:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|7fb5e16a-4c8f23bbfc974667.",
"errors": {
"": [
"A non-empty request body is required."
]
}
}
Typ ValidationProblemDetails
:
- Poskytuje strojově čitelný formát pro určení chyb v odpovědích webového rozhraní API.
- Splňuje specifikaci RFC 7807.
Pokud chcete, aby automatické a vlastní odpovědi byly konzistentní, volejte metodu ValidationProblem místo BadRequest. ValidationProblem
vrátí objekt ValidationProblemDetails i automatickou odpověď.
Protokolování automatických odpovědí 400
Projděte si téma Postup protokolování automatických odpovědí 400 u chyb ověření modelu (dotnet/AspNetCore.Docs#12157).
Zákaz automatické odpovědi 400
Chcete-li zakázat automatické chování 400, nastavte vlastnost SuppressModelStateInvalidFilter na true
. Přidejte následující zvýrazněný kód v Startup.ConfigureServices
:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
});
Odvozování parametrů zdroje vazby
Atribut zdroje vazby definuje umístění, ve kterém se nachází hodnota parametru akce. Existují následující zdrojové atributy vazby:
Atribut | Zdroj vazby |
---|---|
[FromBody] |
Text požadavku |
[FromForm] |
Formulářová data v textu požadavku |
[FromHeader] |
Hlavička požadavku |
[FromQuery] |
Parametr řetězce dotazu požadavku |
[FromRoute] |
Směrování dat z aktuálního požadavku |
[FromServices] |
Služba požadavku vložená jako parametr akce |
Upozorňující
Nepoužívejte [FromRoute]
, pokud hodnoty mohou obsahovat %2f
(to znamená /
). %2f
se nepřevedou na /
. Pokud hodnota může obsahovat %2f
, použijte [FromQuery]
.
Bez atributu [ApiController]
nebo atributů zdroje vazby, jako je [FromQuery]
, se modul runtime ASP.NET Core pokusí použít komplexní objektový vazač modelů. Komplexní objektový vazač modelů načítá data z poskytovatelů hodnot v definovaném pořadí.
V následujícím příkladu atribut [FromQuery]
označuje, že hodnota parametru discontinuedOnly
je poskytnuta v řetězci dotazu adresy URL požadavku:
[HttpGet]
public ActionResult<List<Product>> Get(
[FromQuery] bool discontinuedOnly = false)
{
List<Product> products = null;
if (discontinuedOnly)
{
products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
}
else
{
products = _productsInMemoryStore;
}
return products;
}
Atribut [ApiController]
používá odvozená pravidla pro výchozí zdroje dat parametrů akce. Tato pravidla vám ušetří nutnost ručně identifikovat zdroje vazeb použitím atributů na parametry akce. Odvozená pravidla zdroje vazby se chovají takto:
[FromBody]
se odvozuje pro parametry komplexního typu. Výjimkou pro odvozené pravidlo[FromBody]
je libovolný komplexní předdefinovaný typ se speciálním významem, jako je IFormCollection a CancellationToken. Kód odvození zdroje vazby tyto speciální typy ignoruje.[FromForm]
se odvozuje pro parametry typu IFormFile a IFormFileCollection. Neodvozuje se pro žádné jednoduché nebo uživatelsky definované typy.[FromRoute]
se odvozuje pro libovolný název parametru akce odpovídající parametru v šabloně trasy. Pokud parametru akce odpovídá více než jedna trasa, za[FromRoute]
se považuje libovolná hodnota trasy.[FromQuery]
se odvozuje pro všechny ostatní parametry.
Poznámky k odvozování FromBody
[FromBody]
se neodvozuje pro jednoduché typy, jako je string
nebo int
. Proto by se atribut [FromBody]
měl pro jednoduché typy používat, pokud je tato funkce potřebná.
Pokud má akce více parametrů vázaných z textu požadavku, vyvolá se výjimka. Například všechny následující podpisy metody akce způsobují výjimku:
[FromBody]
se odvozuje v obou případech, protože jde o komplexní typy.[HttpPost] public IActionResult Action1(Product product, Order order)
Atribut
[FromBody]
v jednom případě, odvozený v druhém, protože jde o komplexní typ.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Atribut
[FromBody]
v obou případech.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Poznámka:
V ASP.NET Core 2.1 se parametry typu kolekce, jako jsou seznamy a pole, nesprávně odvozují jako [FromQuery]
. Pro tyto parametry by měl být použit atribut [FromBody]
, pokud mají být vázány z textu požadavku. Toto chování je opraveno v ASP.NET Core verze 2.2 nebo novější, kde se parametry typu kolekce ve výchozím nastavení odvozují z textu.
Zákaz odvozených pravidel
Pokud chcete zakázat odvozování zdroje vazby, nastavte SuppressInferBindingSourcesForParameters na true
. V souboru Startup.ConfigureServices
přidejte následující kód:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
});
Odvozování požadavků multipart/form-data
Atribut [ApiController]
použije odvozené pravidlo pro parametry akce typu IFormFile a IFormFileCollection. Typ obsahu požadavku multipart/form-data
je odvozený pro tyto typy.
Pokud chcete zakázat výchozí chování, nastavte vlastnost SuppressConsumesConstraintForFormFileParameters na true
v Startup.ConfigureServices
:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
});
Podrobnosti o problému se stavovými kódy chyb
Pokud je verze kompatibility 2.2 nebo novější, MVC transformuje výsledek chyby (výsledek se stavovým kódem 400 nebo vyšším) na výsledek s ProblemDetails. Typ ProblemDetails
je založený na specifikaci RFC 7807 pro poskytování strojově čitelných podrobností o chybě v odpovědi HTTP.
Zvažte použití následujícího kódu v akci kontroleru:
if (pet == null)
{
return NotFound();
}
Metoda NotFound
vytvoří stavový kód HTTP 404 s textem ProblemDetails
. Příklad:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Zákaz odpovědi ProblemDetails
Automatické vytvoření ProblemDetails
pro stavové kódy kódů chyb je zakázáno, pokud je vlastnost SuppressMapClientErrors nastavená na true
. V souboru Startup.ConfigureServices
přidejte následující kód:
Definování podporovaných typů obsahu požadavku s atributem [Consumes]
Akce ve výchozím nastavení podporuje všechny dostupné typy obsahu požadavku. Pokud je například aplikace nakonfigurovaná tak, aby podporovala vstupní formátovací moduly JSON i XML, akce podporuje více typů obsahu, včetně application/json
a application/xml
.
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavku. Atribut [Consumes]
použijte u akce nebo kontroleru s určením jednoho nebo několika typů obsahu:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Akce CreateProduct
v předchozím kódu určuje typ obsahu application/xml
. Požadavky směrované na tuto akci musí zadat hlavičku Content-Type
typu application/xml
. Požadavky, které neurčují hlavičku Content-Type
typu application/xml
, vedou k odpovědi 415 Nepodporovaný typ média.
Atribut [Consumes]
také akci umožňuje ovlivnit její výběr na základě typu obsahu příchozího požadavku, a to použitím omezení typu. Představte si následující příklad:
[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
[HttpPost]
[Consumes("application/json")]
public IActionResult PostJson(IEnumerable<int> values) =>
Ok(new { Consumes = "application/json", Values = values });
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}
V předchozím kódu je třída ConsumesController
nakonfigurovaná tak, aby zpracovávala požadavky odeslané na adresu URL https://localhost:5001/api/Consumes
. Obě akce kontroleru, PostJson
i PostForm
, zpracovávají požadavky POST se stejnou adresou URL. Bez atributu [Consumes]
aplikujícího omezení výjimky se vyvolá výjimka nejednoznačné shody.
Atribut [Consumes]
se použije u obou akcí. Akce PostJson
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/json
. Akce PostForm
zpracovává požadavky odeslané s hlavičkou Content-Type
typu application/x-www-form-urlencoded
.
Další materiály
- Návratové typy akcí kontroleru ve webovém rozhraní API ASP.NET Core
- Zpracování chyb ve webových rozhraních API založených na řadiči jádra ASP.NET
- Vlastní formátovací moduly ve webových rozhraních API ASP.NET Core
- Formátování dat odpovědí ve webovém rozhraní API ASP.NET Core
- Dokumentace k webovému rozhraní API ASP.NET Core s využitím Swaggeru/OpenAPI
- Směrování na akce kontroleru v ASP.NET Core
- Vytvoření webového rozhraní API pomocí ASP.NET Core