Vytváření webových rozhraní API pomocí ASP.NET Core

Scott Addie a Dykstra

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 zpracovává žádosti pomocí řadičů. Řadiče ve webovém rozhraní API jsou třídy, které jsou odvozeny z ControllerBase . V tomto článku se dozvíte, jak používat řadiče pro zpracování požadavků webového rozhraní API.

Zobrazit nebo stáhnout vzorový kód. (Stažení).

ControllerBase – třída

Webové rozhraní API se skládá z jedné nebo více tříd kontroleru, které jsou odvozeny z ControllerBase . Šablona projektu webového rozhraní API poskytuje kontroler Starter:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

Nevytvářejte kontroler webového rozhraní API odvozením z Controller třídy. Controller je odvozen z ControllerBase a přidává podporu pro zobrazení, aby bylo možné zpracovávat webové stránky, nikoli požadavky webového rozhraní API. Toto pravidlo má výjimku: Pokud plánujete použít stejný kontroler pro obě zobrazení a webová rozhraní API, odvodit je od Controller .

ControllerBaseTřída 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);
}

Zde je několik příkladů metod, které ControllerBase poskytuje.

Metoda Poznámky
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í naleznete v tématu ControllerBase .

Atributy

Microsoft.AspNetCore.MvcObor názvů poskytuje atributy, které lze použít ke konfiguraci chování řadičů webového rozhraní API a metod akcí. Následující příklad používá atributy k určení podporovaného příkazu 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 příkladů atributů, které jsou k dispozici.

Atribut Poznámky
[Route] Určuje vzor adresy URL pro kontroler nebo akci.
[Bind] Určuje předponu a vlastnosti, které se mají zahrnout do vazby modelu.
[HttpGet] Identifikuje akci, která podporuje příkaz akce HTTP GET.
[Consumes] Určuje datové typy, které akce akceptuje.
[Produces] Určuje datové typy, které akce vrátí.

Seznam, který obsahuje dostupné atributy, najdete v tématu Microsoft.AspNetCore.Mvc obor názvů.

ApiController – atribut

[ApiController]Atribut lze použít pro třídu kontroleru a povolit následující dogmatickým chování specifické pro rozhraní API:

Podrobnosti o problému pro stavové kódy chyb vyžadují kompatibilitu verze 2,2 nebo novější. Ostatní funkce vyžadují verzi kompatibility 2,1 nebo novější.

Tyto funkce vyžadují kompatibilitu verze 2,1 nebo novější.

Atribut na určitých řadičích

[ApiController]Atribut lze použít pro konkrétní řadiče, jako v následujícím příkladu, ze šablony projektu:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

Atribut na více řadičích

Jedním z přístupů k použití atributu na více než jednom řadiči je vytvoření vlastní třídy základního kontroleru s poznámkou s [ApiController] atributem. Následující příklad ukazuje vlastní základní třídu a řadič, který je z něj odvozen:

[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase

Atribut na sestavení

Pokud je verze kompatibility nastavena na 2,2 nebo novější, [ApiController] atribut lze použít na sestavení. Anotace tímto způsobem aplikuje chování webového rozhraní API na všechny řadiče v sestavení. Neexistuje žádný způsob, jak odhlásit jednotlivé řadiče. Použijte atribut na úrovni sestavení pro deklaraci oboru názvů obklopující Startup třídu:

[assembly: ApiController]
namespace WebApiSample
{
    public class Startup
    {
        ...
    }
}

Požadavek na směrování atributu

[ApiController]Atribut dělá směrování požadavku. Napří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

[ApiController]Atribut způsobuje chyby ověření modelu automaticky a odpověď HTTP 400. V důsledku toho následující kód není zbytečný v metodě akce:

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}

ASP.NET Core MVC používá ModelStateInvalidFilter Filtr akcí k provedení předchozí kontroly.

Výchozí odpověď důvodu chybného požadavku

V případě kompatibility verze 2,1 je výchozí typ odpovědi pro odpověď HTTP 400 SerializableError . Následující text žádosti je příkladem serializovaného typu:

{
  "": [
    "A non-empty request body is required."
  ]
}

V případě kompatibility verze 2,2 nebo novější je výchozí typ odpovědi pro odpověď HTTP 400 ValidationProblemDetails . Následující text žádosti 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."
    ]
  }
}

ValidationProblemDetailsTyp:

  • Poskytuje strojově čitelný formát pro zadávání chyb v odpovědích webového rozhraní API.
  • Vyhovuje specifikaci RFC 7807.

Chcete-li zajistit konzistenci automatických a vlastních odpovědí, zavolejte ValidationProblem metodu místo BadRequest . ValidationProblem Vrátí ValidationProblemDetails objekt a také automatickou odpověď.

Protokolovat automatické odpovědi 400

Přečtěte si, Jak protokolovat automatické odpovědi 400 pro chyby ověření modelu (dotnet/AspNetCore.Docs # 12157).

Zakázat automatickou odpověď 400

Chcete-li zakázat automatické chování 400, nastavte SuppressModelStateInvalidFilter vlastnost na hodnotu true . Do následujícího pole přidejte následující zvýrazněný kód 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";
    });

Odvození zdrojového parametru vazby

Zdrojový atribut vazby definuje umístění, kde je nalezena hodnota parametru akce. Existují následující zdrojové atributy vazby:

Atribut Zdroj vazby
[FromBody] Text požadavku
[FromForm] Data formuláře v textu žádosti
[FromHeader] Hlavička požadavku
[FromQuery] Parametr řetězce dotazu žádosti
[FromRoute] Směrovat data z aktuální žádosti
[FromServices] Služba požadavku byla vložena jako parametr akce.

Upozornění

Nepoužívejte [FromRoute] , pokud hodnoty mohou obsahovat %2f (to znamená / ). %2f nedá se odsekvencit na / . Použijte [FromQuery] , pokud hodnota může obsahovat %2f .

Bez atributu nebo atributů zdroje vazby, jako je , se ASP.NET Core runtime pokusí použít komplexní vazbu [ApiController] [FromQuery] modelu objektů. Komplexní vazač objektového modelu načítá data ze zprostředkovatelů hodnot v definovaném pořadí.

V následujícím příkladu atribut indikuje, že hodnota parametru je zadaná v řetězci dotazu [FromQuery] adresy URL discontinuedOnly 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] aplikuje pravidla odvozování pro výchozí zdroje dat parametrů akce. Tato pravidla vám ušetří možnost identifikovat zdroje vazeb ručně použitím atributů na parametry akce. Pravidla odvození zdroje vazby se chovají takto:

  • [FromBody] se odvodí pro komplexní parametry typu. Výjimkou z pravidla odvozování je jakýkoli složitý předdefinované typy se speciálním [FromBody] významem, například IFormCollection a CancellationToken . Kód odvození zdroje vazby ignoruje tyto speciální typy.
  • [FromForm] je odvozena pro parametry akce typu a IFormFile IFormFileCollection . Nevyvozuje se pro žádné jednoduché nebo uživatelem definované typy.
  • [FromRoute] se odvodí pro jakýkoli název parametru akce odpovídající parametru v šabloně trasy. Pokud parametr akce odpovídá více tras, jakákoli hodnota trasy se považuje za [FromRoute] .
  • [FromQuery] se odvodí pro všechny ostatní parametry akce.

Poznámky k odvozování ztělesnění

[FromBody] se nevyvozuje pro jednoduché typy, jako je string nebo int . Proto by atribut [FromBody] měl být použit pro jednoduché typy v případě, že je tato funkce potřebná.

Pokud má akce více než jeden parametr svázaný s tělem požadavku, je vyvolána výjimka. Například všechny signatury metod akce způsobí výjimku:

  • [FromBody] z obou z toho vyvozené, protože se o komplexní typy.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] atribut na jednom, odvozený od druhého, protože se jedná o komplexní typ.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] pro oba atributy.

    [HttpPost]
    public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
    

Zákaz pravidel odvozování

Pokud chcete zakázat odvození zdroje vazby, nastavte SuppressInferBindingSourcesForParameters na true . Do souboru přidejte následující Startup.ConfigureServices 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";
    });

Odvozování požadavků na vícedílné nebo formulářové data

Atribut [ApiController] použije pravidlo odvozování, pokud je parametr akce anotován [FromForm] atributem . Typ multipart/form-data obsahu požadavku je odvozený.

Pokud chcete výchozí chování zakázat, nastavte SuppressConsumesConstraintForFormFileParameters vlastnost 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";
    });

Podrobnosti o problémech se stavové kódy chyb

Pokud je verze kompatibility 2.2 nebo novější, MVC transformuje výsledek chyby (výsledek se stavový 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ách v odpovědi HTTP.

V akci kontroleru zvažte následující kód:

if (pet == null)
{
    return NotFound();
}

Metoda NotFound vytvoří stavový kód HTTP 404 s ProblemDetails tělem. Napří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í pro ProblemDetails stavové kódy chyb je zakázané, když SuppressMapClientErrors je vlastnost nastavená na true . Do souboru přidejte následující Startup.ConfigureServices 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";
    });

Definování podporovaných typů obsahu požadavků s atributem [Consumes]

Ve výchozím nastavení akce podporuje všechny dostupné typy obsahu požadavků. Pokud je například aplikace nakonfigurovaná tak, aby podporovala formátovací funkce vstupu JSONi XML, akce podporuje více typů obsahu, včetně a application/json application/xml .

Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavků. Použijte atribut [Consumes] na akci nebo kontroler a určete jeden nebo více typů obsahu:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

V předchozím kódu akce CreateProduct určuje typ obsahu application/xml . Požadavky směrované na tuto akci musí obsahovat Content-Type hlavičku application/xml . Požadavky, které nezadá Content-Type hlavičku výsledku v odpovědi application/xml 415 Nepodporovaný typ média.

Atribut také umožňuje akci ovlivnit výběr na základě typu obsahu příchozího požadavku použitím [Consumes] omezení typu. Uvažujte 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 nakonfigurován pro ConsumesController zpracování požadavků odeslaných na adresu https://localhost:5001/api/Consumes URL. Obě akce kontroleru a PostJson PostForm zovládá požadavky POST se stejnou adresou URL. Bez použití [Consumes] atributu omezení typu je vyvolána výjimka nejednoznačné shody.

Atribut [Consumes] se použije u obou akcí. Akce PostJson zpracovává požadavky odeslané pomocí Content-Type hlavičky application/json . Akce PostForm zpracovává požadavky odeslané pomocí Content-Type hlavičky application/x-www-form-urlencoded .

Další zdroje informací

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Nevytvářejte kontroler webového rozhraní API odvozením z Controller třídy . Controller je odvozený od zobrazení a přidává podporu pro zobrazení, takže slouží ke zpracování webových ControllerBase stránek, nikoli požadavků webového rozhraní API. Toto pravidlo má výjimku: Pokud plánujete používat stejný kontroler pro zobrazení i webová rozhraní API, odvozte ho z Controller .

Třída ControllerBase poskytuje mnoho vlastností a metod, které jsou užitečné pro zpracování požadavků HTTP. Například vrátí ControllerBase.CreatedAtAction 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 poskytujeme.

Metoda Poznámky
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 Microsoft.AspNetCore.Mvc názvů 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é akce HTTP operace a všechny známé stavové kódy 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 Poznámky
[Route] Určuje vzor adresy URL kontroleru nebo akce.
[Bind] Určuje předponu a vlastnosti, které se mají zahrnout pro vazbu modelu.
[HttpGet] Identifikuje akci, která podporuje příkaz akce HTTP GET.
[Consumes] Určuje datové typy, které akce přijímá.
[Produces] Určuje datové typy, které akce vrátí.

Seznam, který obsahuje dostupné atributy, najdete v oboru Microsoft.AspNetCore.Mvc názvů .

Atribut ApiController

Atribut [ApiController] lze použít na třídu kontroleru, aby bylo možné následující názorné chování specifické pro rozhraní API:

Funkce Podrobnosti o problémech pro kódy stavu chyb vyžaduje verzi kompatibility 2.2 nebo novější. Ostatní funkce vyžadují verzi kompatibility 2.1 nebo novější.

Tyto funkce vyžadují verzi kompatibility 2.1 nebo novější.

Atribut na konkrétních řadičích

Atribut [ApiController] lze použít na konkrétní kontrolery, jako v následujícím příkladu ze šablony projektu:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Atribut na více řadičích

Jedním z přístupů k použití atributu ve více než jednom kontroleru je vytvoření vlastní třídy základního kontroleru s poznámkami k [ApiController] atributu . Následující příklad ukazuje vlastní základní třídu a kontroler, který je z ní odvozen:

[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("api/[controller]")]
public class PetsController : MyControllerBase

Atribut v sestavení

Pokud je verze kompatibility nastavena na 2.2 nebo novější, lze atribut [ApiController] použít na sestavení. Poznámka tímto způsobem aplikuje chování webového rozhraní API na všechny kontrolery v sestavení. Neexistuje žádný způsob, jak vyjádřit výslovný nesouhlas s jednotlivými řadiči. Použijte atribut na úrovni sestavení na deklaraci oboru názvů obklopující Startup třídu:

[assembly: ApiController]
namespace WebApiSample
{
    public class Startup
    {
        ...
    }
}

Požadavek na směrování atributů

Atribut [ApiController] vytváří směrování atributů jako požadavek. Například:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Akce jsou nepřístupné prostřednictvím konvenčních tras definovaných v nebo UseMvc v UseMvcWithDefaultRoute Startup.Configure .

Automatické odpovědi HTTP 400

Atribut [ApiController] automaticky aktivuje odpověď HTTP 400 při ověřování modelu. 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 používá ModelStateInvalidFilter filtr akcí k předchozí kontrole.

Odpověď Default BadRequest

Ve verzi kompatibility 2.1 je výchozí typ odpovědi pro odpověď HTTP 400 SerializableError . Následující text požadavku je příkladem serializovaného typu:

{
  "": [
    "A non-empty request body is required."
  ]
}

Ve verzi kompatibility 2.2 nebo novější je výchozí typ odpovědi pro odpověď HTTP 400 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."
    ]
  }
}

ValidationProblemDetailsTyp:

  • Poskytuje strojově čitelný formát pro zadávání chyb v odpovědích webového rozhraní API.
  • Je v souladu se specifikací RFC 7807.

Pokud chcete zajistit konzistentní automatické a vlastní odpovědi, volejte ValidationProblem metodu místo BadRequest . ValidationProblem vrací ValidationProblemDetails objekt i automatickou odpověď.

Protokolování automatických odpovědí 400

Viz Protokolování automatických odpovědí 400 u chyb ověření modelu (dotnet/AspNetCore.Docs#12157).

Zákaz automatické odpovědi 400

Pokud chcete zakázat automatické chování 400, nastavte SuppressModelStateInvalidFilter vlastnost na true . Do souboru přidejte následující zvýrazněný Startup.ConfigureServices kód:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

Odvození parametru zdroje vazby

Zdrojový atribut vazby definuje umístění, ve kterém se nachází hodnota parametru akce. Existují následující atributy zdroje vazby:

Atribut Zdroj vazby
[FromBody] Text požadavku
[FromForm] Data formuláře 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 žádosti injektovaná jako parametr akce

Upozornění

Nepoužívejte, pokud [FromRoute] hodnoty mohou obsahovat %2f (to znamená / ). %2f se nepřidá do / . Použijte, [FromQuery] pokud hodnota může obsahovat %2f .

Bez atributu nebo atributů zdroje vazby, jako je , se ASP.NET Core runtime pokusí použít komplexní vazbu [ApiController] [FromQuery] modelu objektů. Komplexní vazač objektového modelu načítá data ze zprostředkovatelů hodnot v definovaném pořadí.

V následujícím příkladu atribut indikuje, že hodnota parametru je zadaná v řetězci dotazu [FromQuery] adresy URL discontinuedOnly 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] aplikuje pravidla odvozování pro výchozí zdroje dat parametrů akce. Tato pravidla vám ušetří možnost identifikovat zdroje vazeb ručně použitím atributů na parametry akce. Pravidla odvození zdroje vazby se chovají takto:

  • [FromBody] se odvodí pro komplexní parametry typu. Výjimkou z pravidla odvozování je jakýkoli složitý předdefinované typy se speciálním [FromBody] významem, například IFormCollection a CancellationToken . Kód odvození zdroje vazby ignoruje tyto speciální typy.
  • [FromForm] je odvozena pro parametry akce typu a IFormFile IFormFileCollection . Nevyvozuje se pro žádné jednoduché nebo uživatelem definované typy.
  • [FromRoute] se odvodí pro jakýkoli název parametru akce odpovídající parametru v šabloně trasy. Pokud parametr akce odpovídá více tras, jakákoli hodnota trasy se považuje za [FromRoute] .
  • [FromQuery] se odvodí pro všechny ostatní parametry akce.

Poznámky k odvozování ztělesnění

[FromBody] se nevyvozuje pro jednoduché typy, jako je string nebo int . Proto by atribut [FromBody] měl být použit pro jednoduché typy v případě, že je tato funkce potřebná.

Pokud má akce více než jeden parametr svázaný s tělem požadavku, je vyvolána výjimka. Například všechny signatury metod akcí způsobují výjimku:

  • [FromBody] z obou z toho vyvozené, protože se o komplexní typy.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] atribut na jednom, odvozený od druhého, protože se jedná o komplexní typ.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] pro oba atributy.

    [HttpPost]
    public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
    

Poznámka

V ASP.NET Core 2.1 jsou parametry typu kolekce, jako jsou seznamy a pole, nesprávně odvozeny jako [FromQuery] . Atribut by se měl použít pro tyto parametry, pokud mají [FromBody] být vázány z textu požadavku. Toto chování je opraveno v ASP.NET Core 2.2 nebo novějším, kde parametry typu kolekce jsou odvozeny jako vázané z těla ve výchozím nastavení.

Zákaz pravidel odvozování

Pokud chcete zakázat odvození zdroje vazby, nastavte SuppressInferBindingSourcesForParameters na true . Do souboru přidejte následující Startup.ConfigureServices kód:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

Odvozování požadavků na vícedílné nebo formulářové data

Atribut [ApiController] použije pravidlo odvozování, pokud je parametr akce anotován [FromForm] atributem . multipart/form-dataVyvozuje se typ obsahu požadavku.

Pokud chcete výchozí chování zakázat, nastavte SuppressConsumesConstraintForFormFileParameters vlastnost na true v Startup.ConfigureServices :

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

Podrobnosti o problémech se stavové kódy chyb

Pokud je verze kompatibility 2.2 nebo novější, MVC transformuje výsledek chyby (výsledek se stavový 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ách v odpovědi HTTP.

V akci kontroleru zvažte následující kód:

if (pet == null)
{
    return NotFound();
}

Metoda NotFound vytvoří stavový kód HTTP 404 s ProblemDetails tělem. Napří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í pro ProblemDetails stavové kódy chyb je zakázané, když SuppressMapClientErrors je vlastnost nastavená na true . Do souboru přidejte následující Startup.ConfigureServices kód:

Definování podporovaných typů obsahu požadavků s atributem [Consumes]

Ve výchozím nastavení akce podporuje všechny dostupné typy obsahu požadavků. Pokud je například aplikace nakonfigurovaná tak, aby podporovala formátovací funkce vstupu JSONi XML, akce podporuje více typů obsahu, včetně a application/json application/xml .

Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavků. Použijte atribut [Consumes] na akci nebo kontroler a určete jeden nebo více typů obsahu:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

V předchozím kódu akce CreateProduct určuje typ obsahu application/xml . Požadavky směrované na tuto akci musí obsahovat Content-Type hlavičku application/xml . Požadavky, které nezadá Content-Type hlavičku výsledku v odpovědi application/xml 415 Nepodporovaný typ média.

Atribut také umožňuje akci ovlivnit výběr na základě typu obsahu příchozího požadavku použitím [Consumes] omezení typu. Uvažujte 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 nakonfigurován pro ConsumesController zpracování požadavků odeslaných na adresu https://localhost:5001/api/Consumes URL. Obě akce kontroleru a PostJson PostForm zovládá požadavky POST se stejnou adresou URL. Bez použití [Consumes] atributu omezení typu je vyvolána výjimka nejednoznačné shody.

Atribut [Consumes] se použije u obou akcí. Akce PostJson zpracovává požadavky odeslané pomocí Content-Type hlavičky application/json . Akce PostForm zpracovává požadavky odeslané pomocí Content-Type hlavičky application/x-www-form-urlencoded .

Další zdroje informací