Návratové typy akcí kontroleru ve webovém rozhraní API ASP.NET Core

Zobrazení nebo stažení ukázkového kódu (jak stáhnout)

ASP.NET Core nabízí následující možnosti pro návratové typy akcí kontroleru webového rozhraní API:

Tento dokument vysvětluje, kdy je nejvhodnější použít každý návratový typ.

Konkrétní typ

Nejjednodušší akce vrátí primitivní nebo složitý datový typ (například string vlastní typ objektu). Zvažte následující akci, která vrací kolekci vlastních Product objektů:

[HttpGet]
public List<Product> Get() =>
    _repository.GetProducts();

Bez známých podmínek k ochraně před provedením akce může být stačit vrácení konkrétního typu. Předchozí akce nepřijímá žádné parametry, takže ověření omezení parametrů není potřeba.

Pokud je možné použít více návratových typů, je běžné kombinovat návratový ActionResult typ s primitivním nebo komplexním návratovým typem. K přizpůsobení tohoto typu akce je potřeba buď IActionResult , nebo ActionResult<T> . V tomto dokumentu je k dispozici několik ukázek více návratových typů.

Vrácení IEnumerable<T> nebo IAsyncEnumerable<T>

ASP.NET Core uloží do vyrovnávací paměti výsledek akcí, které se vrátí IEnumerable<T> před zápisem do odpovědi. Zvažte deklarování návratového typu podpisu akce tak, aby IAsyncEnumerable<T> se zajistil asynchronní iterace. V konečném důsledku je režim iterace založen na návratu základního konkrétního typu. MVC automaticky do vyrovnávací paměti jakýkoli konkrétní typ, který implementuje IAsyncEnumerable<T>.

Zvažte následující akci, která vrací záznamy o produktech s prodejní cenou jako IEnumerable<Product>:

[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
    var products = _repository.GetProducts();

    foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

Ekvivalentem IAsyncEnumerable<Product> předchozí akce je:

[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
    var products = _repository.GetProductsAsync();

    await foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

Typ IActionResult

Návratový IActionResult typ je vhodný, pokud je v akci možné více ActionResult návratových typů. Typy ActionResult představují různé stavové kódy HTTP. Všechny ne abstraktní třídy odvozené z ActionResult kvalifikací jako platný návratový typ. Mezi běžné návratové typy v této kategorii patří BadRequestResult (400), NotFoundResult (404) a OkObjectResult (200). Alternativně lze metody pohodlí ve ControllerBase třídě použít k vrácení ActionResult typů z akce. Například return BadRequest(); je zkrácená forma return new BadRequestResult();.

Vzhledem k tomu, že v tomto typu akce existuje více návratových typů a cest, je nutné použít tento atribut.[ProducesResponseType] Tento atribut vytváří popisnější podrobnosti odpovědi pro stránky nápovědy webového rozhraní API generované nástroji, jako je Swagger. [ProducesResponseType] označuje známé typy a stavové kódy HTTP, které mají být vráceny akcí.

Synchronní akce

Zvažte následující synchronní akci, ve které existují dva možné návratové typy:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return Ok(product);
}

V předchozí akci:

  • Stavový kód 404 se vrátí, když produkt reprezentovaný id v podkladovém úložišti dat neexistuje. Metoda NotFound pohodlí je vyvolána jako zkratka pro return new NotFoundResult();.
  • Stavový kód 200 se vrátí s objektem Product , když produkt existuje. Metoda Ok pohodlí je vyvolána jako zkratka pro return new OkObjectResult(product);.

Asynchronní akce

Zvažte následující asynchronní akci, ve které existují dva možné návratové typy:

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    await _repository.AddProductAsync(product);

    return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}

V předchozí akci:

  • Stavový kód 400 se vrátí, když popis produktu obsahuje "Widget XYZ". Metoda BadRequest pohodlí je vyvolána jako zkratka pro return new BadRequestResult();.
  • Stavový kód 201 je generován metodou CreatedAtAction pohodlí při vytvoření produktu. Alternativou k volání CreatedAtAction je return new CreatedAtActionResult(nameof(GetById), "Products", new { id = product.Id }, product);. V této cestě Product kódu je objekt poskytnut v textu odpovědi. Je Location k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.

Například následující model označuje, že požadavky musí obsahovat Name vlastnosti a Description vlastnosti. Selhání poskytování Name a Description v požadavku způsobí selhání ověření modelu.

public class Product
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Description { get; set; }

    public bool IsOnSale { get; set; }
}

Pokud se [ApiController] atribut použije, chyby ověření modelu způsobí stavový kód 400. Další informace najdete v tématu Automatické odpovědi HTTP 400.

ActionResult vs IActionResult

Následující část porovnává ActionResult s IActionResult

Typ ActionResult<T>

ASP.NET Core obsahuje návratový typ ActionResult<T> pro akce kontroleru webového rozhraní API. Umožňuje vrátit typ odvozený nebo ActionResult vrátit určitý typ. ActionResult<T> nabízí následující výhody oproti typu IActionResult:

  • Vlastnost [ProducesResponseType] atributu Type lze vyloučit. Například [ProducesResponseType(200, Type = typeof(Product))] je zjednodušená na [ProducesResponseType(200)]. Očekávaný návratový typ akce se místo toho odvozuje z in TActionResult<T>.
  • Implicitní operátory přetypování podporují převod obou T a ActionResult na ActionResult<T>. T převede na ObjectResult, což znamená return new ObjectResult(T); , že je zjednodušená na return T;.

Jazyk C# nepodporuje implicitní operátory přetypování v rozhraních. V důsledku toho je převod rozhraní na konkrétní typ nezbytný k použití ActionResult<T>. Například použití IEnumerable v následujícím příkladu nefunguje:

[HttpGet]
public ActionResult<IEnumerable<Product>> Get() =>
    _repository.GetProducts();

Jednou z možností, jak opravit předchozí kód, je vrátit _repository.GetProducts().ToList();.

Většina akcí má konkrétní návratový typ. Během provádění akce může dojít k neočekávaným podmínkám, v takovém případě se konkrétní typ nevrátí. Například vstupní parametr akce může selhat ověření modelu. V takovém případě je běžné místo konkrétního typu vrátit odpovídající ActionResult typ.

Synchronní akce

Zvažte synchronní akci, ve které existují dva možné návratové typy:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return product;
}

V předchozí akci:

  • Stavový kód 404 se vrátí, když produkt v databázi neexistuje.
  • Stavový kód 200 se vrátí s odpovídajícím Product objektem, pokud produkt existuje.

Asynchronní akce

Zvažte asynchronní akci, ve které existují dva možné návratové typy:

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    await _repository.AddProductAsync(product);

    return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}

V předchozí akci:

  • Stavový kód 400 (BadRequest) vrátí modul runtime ASP.NET Core, když:
    • Atribut [ApiController] byl použit a ověření modelu selže.
    • Popis produktu obsahuje "XYZ Widget".
  • Stavový kód 201 se vygeneruje metodou CreatedAtAction při vytvoření produktu. V této cestě Product kódu je objekt poskytnut v textu odpovědi. Je Location k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.

Další materiály