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 proreturn new NotFoundResult();
. - Stavový kód 200 se vrátí s objektem
Product
, když produkt existuje. Metoda Ok pohodlí je vyvolána jako zkratka proreturn 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
jereturn new CreatedAtActionResult(nameof(GetById), "Products", new { id = product.Id }, product);
. V této cestěProduct
kódu je objekt poskytnut v textu odpovědi. JeLocation
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]
atributuType
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 inT
ActionResult<T>
. - Implicitní operátory přetypování podporují převod obou
T
aActionResult
naActionResult<T>
.T
převede na ObjectResult, což znamenáreturn new ObjectResult(T);
, že je zjednodušená nareturn 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".
- Atribut
- 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. JeLocation
k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.