Návratové typy akcí kontroleru ve webovém rozhraní API ASP.NET Core
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
ASP.NET Core nabízí následující možnosti návratových typů akcí kontroleru webového rozhraní API:
Tento článek vysvětluje, kdy je nejvhodnější použít každý návratový typ.
Konkrétní typ
Nejzákladnější akce vrátí primitivní nebo složitý datový typ, například string
nebo vlastní objekt. Představte si následující akci, která vrací kolekci vlastních Product
objektů:
[HttpGet]
public Task<List<Product>> Get() =>
_productContext.Products.OrderBy(p => p.Name).ToListAsync();
Bez známých podmínek pro ochranu před tím, aby vrácení určitého typu mohlo stačit. 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 článku je k dispozici několik ukázek více návratových typů.
Vrátit IEnumerable<T> nebo IAsyncEnumerable<T>
Podívejte se na informace o vrácení IEnumerable<T>
nebo IAsyncEnumerable<T>
výkonu.
ASP.NET Core uloží do vyrovnávací paměti výsledek akcí, které se vrátí IEnumerable<T> před jejich zápisem do odpovědi. Zvažte deklaraci návratového typu podpisu akce, který IAsyncEnumerable<T> zaručuje asynchronní iteraci. V konečném důsledku je režim iterace založený na vrácených podkladových betonových typech a vybraný formátovací modul ovlivňuje způsob zpracování výsledku:
- Když používáte
System.Text.Json
formátovací modul, MVC spoléhá na podporu přidanouSystem.Text.Json
do streamu výsledku. - Při použití
Newtonsoft.Json
nebo s formátovánímXML-based
je výsledek uložen do vyrovnávací paměti.
Vezměte v úvahu následující akci, která vrací záznamy o produktech s cenami prodeje jako IEnumerable<Product>
:
[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
var products = _productContext.Products.OrderBy(p => p.Name).ToList();
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 = _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable();
await foreach (var product in products)
{
if (product.IsOnSale)
{
yield return product;
}
}
}
Typ IActionResult
Návratový IActionResult typ je vhodný, pokud je možné v akci provést více ActionResult
návratových typů. Typy ActionResult
představují různé stavové kódy HTTP. Každá ne abstraktní třída odvozená z ActionResult
kvalifikuje 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 atribut liberalně [ProducesResponseType]
. Tento atribut vytvoří 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<Product>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById_IActionResult(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? NotFound() : 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
, pokud produkt existuje. Metoda Ok pohodlí je vyvolána jako zkratka proreturn new OkObjectResult(product);
.
Asynchronní akce
Vezměte v úvahu 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_IActionResult(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
return CreatedAtAction(nameof(CreateAsync_IActionResult), new { id = product.Id }, product);
}
V předchozí akci:
Stavový kód 400 se vrátí, když popis produktu obsahuje "XYZ Widget". 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. Následující kód je alternativou k volání
CreatedAtAction
:return new CreatedAtActionResult(nameof(CreateAsync), "Products", new { id = product.Id }, product);
V předchozí cestě
Product
kódu je objekt zadaný v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Následující model například označuje, že požadavky musí obsahovat vlastnosti Name
a Description
vlastnosti. Neúspěšné zadá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; } = string.Empty;
[Required]
public string Description { get; set; } = string.Empty;
public bool IsOnSale { get; set; }
}
[ApiController]
Pokud se atribut použije, výsledkem chyb ověření modelu je stavový kód 400. Další informace naleznete v tématu Automatické odpovědi HTTP 400.
ActionResult vs IActionResult
Následující část porovnává s ActionResult
IActionResult
Typ ActionResult<T>
ASP.NET Core obsahuje návratový typ ActionResult<T> pro akce kontroleru webového rozhraní API. Umožňuje vrácení typu odvozeného z ActionResult konkrétního typu nebo vrácení určitého typu. ActionResult<T>
nabízí následující výhody oproti typu IActionResult:
[ProducesResponseType]
Vlastnost atributuType
lze vyloučit. Například[ProducesResponseType(200, Type = typeof(Product))]
je zjednodušena na[ProducesResponseType(200)]
. Očekávaný návratový typ akce je odvozen z hodnotyT
inActionResult<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í. Vstupní parametr akce může například 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_ActionResultOfT(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? NotFound() : 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_ActionResultOfT(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
return CreatedAtAction(nameof(CreateAsync_ActionResultOfT), new { id = product.Id }, product);
}
V předchozí akci:
- Stavový kód 400 (BadRequest) vrací 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 je generován metodou CreatedAtAction při vytvoření produktu. V této cestě
Product
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Typ HttpResults
Kromě předdefinovaných typů výsledků MVC (IActionResult a ActionResult<T>) ASP.NET Core obsahuje typy HttpResults , které je možné použít v minimálních rozhraních API i webovém rozhraní API.
Jiné než typy výsledků specifické pro MVC:HttpResults
Jsou implementace výsledků, která je zpracována voláním IResult.ExecuteAsync.
Nevyužít nakonfigurované formátovací moduly. Využití nakonfigurovaných formátovacích nástrojů znamená:
- Některé funkce, jako
Content negotiation
jsou, nejsou dostupné. Content-Type
Produkce je určena implementacíHttpResults
.
- Některé funkce, jako
To HttpResults
může být užitečné při sdílení kódu mezi minimálními rozhraními API a webovým rozhraním API.
Typ IResult
Obor Microsoft.AspNetCore.Http.HttpResults názvů obsahuje třídy, které implementují IResult rozhraní. Rozhraní IResult
definuje kontrakt, který představuje výsledek koncového bodu HTTP. Static Results třída slouží k vytvoření různých IResult
objektů, které představují různé typy odpovědí.
Tabulka předdefinovaných výsledků zobrazuje běžné pomocné rutiny výsledků.
Uvažujte následující kód:
[HttpGet("{id}")]
[ProducesResponseType<Product>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IResult GetById(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? Results.NotFound() : Results.Ok(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, vygenerovaný results.ok <T>().
Uvažujte následující kód:
[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType<Product>(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IResult> CreateAsync(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return Results.BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
var location = Url.Action(nameof(CreateAsync), new { id = product.Id }) ?? $"/{product.Id}";
return Results.Created(location, product);
}
V předchozí akci:
- Stavový kód 400 se vrátí, když:
- Atribut
[ApiController]
byl použit a ověření modelu selže. - Popis produktu obsahuje "XYZ Widget".
- Atribut
- Stavový kód 201 je generován metodou
Results.Create
při vytvoření produktu. V této cestěProduct
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Výsledky<TResult1, typ TResultN>
Static TypedResults třída vrací konkrétní IResult
implementaci, která umožňuje použít IResult
jako návratový typ. Použití konkrétní IResult
implementace nabízí následující výhody oproti typu IResult:
[ProducesResponseType]
Všechny atributy lze vyloučit, protožeHttpResult
implementace přispívá automaticky k metadatům koncového bodu.
Pokud je potřeba více IResult
návratových typů, je vrácení Results<TResult1, TResultN>
upřednostňované před vrácením IResult
. Results<TResult1, TResultN>
Vrácení se upřednostňuje, protože obecné typy sjednocení automaticky uchovávají metadata koncového bodu.
Typy Results<TResult1, TResultN>
sjednocení implementují implicitní operátory přetypování, aby kompilátor mohl automaticky převést typy zadané v obecných argumentech na instanci sjednocovacího typu. To má přidanou výhodu poskytování kontroly času kompilace, že obslužná rutina trasy skutečně vrací pouze výsledky, které deklaruje. Pokus o vrácení typu, který není deklarován jako jeden z obecných argumentů, aby výsledkem Results<>
byla chyba kompilace.
Uvažujte následující kód:
[HttpGet("{id}")]
public Results<NotFound, Ok<Product>> GetById(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? TypedResults.NotFound() : TypedResults.Ok(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, vygenerovaný TypedResults.Ok <T>.
[HttpPost]
public async Task<Results<BadRequest, Created<Product>>> CreateAsync(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return TypedResults.BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
var location = Url.Action(nameof(CreateAsync), new { id = product.Id }) ?? $"/{product.Id}";
return TypedResults.Created(location, product);
}
V předchozí akci:
- Stavový kód 400 se vrátí, když:
- Atribut
[ApiController]
byl použit a ověření modelu selže. - Popis produktu obsahuje "XYZ Widget".
- Atribut
- Stavový kód 201 je generován metodou
TypedResults.Created
při vytvoření produktu. V této cestěProduct
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Další materiály
Zobrazení nebo stažení ukázkového kódu (postup stažení)
ASP.NET Core nabízí následující možnosti návratových typů akcí kontroleru webového rozhraní API:
Tento článek vysvětluje, kdy je nejvhodnější použít každý návratový typ.
Konkrétní typ
Nejzákladnější akce vrátí primitivní nebo složitý datový typ, například string
nebo vlastní objekt. Představte si následující akci, která vrací kolekci vlastních Product
objektů:
[HttpGet]
public Task<List<Product>> Get() =>
_productContext.Products.OrderBy(p => p.Name).ToListAsync();
Bez známých podmínek pro ochranu před tím, aby vrácení určitého typu mohlo stačit. 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 článku je k dispozici několik ukázek více návratových typů.
Vrátit IEnumerable<T> nebo IAsyncEnumerable<T>
Podívejte se na informace o vrácení IEnumerable<T>
nebo IAsyncEnumerable<T>
výkonu.
ASP.NET Core uloží do vyrovnávací paměti výsledek akcí, které se vrátí IEnumerable<T> před jejich zápisem do odpovědi. Zvažte deklaraci návratového typu podpisu akce, který IAsyncEnumerable<T> zaručuje asynchronní iteraci. V konečném důsledku je režim iterace založený na vrácených podkladových betonových typech a vybraný formátovací modul ovlivňuje způsob zpracování výsledku:
- Když používáte
System.Text.Json
formátovací modul, MVC spoléhá na podporu přidanouSystem.Text.Json
do streamu výsledku. - Při použití
Newtonsoft.Json
nebo s formátovánímXML-based
je výsledek uložen do vyrovnávací paměti.
Vezměte v úvahu následující akci, která vrací záznamy o produktech s cenami prodeje jako IEnumerable<Product>
:
[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
var products = _productContext.Products.OrderBy(p => p.Name).ToList();
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 = _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable();
await foreach (var product in products)
{
if (product.IsOnSale)
{
yield return product;
}
}
}
Typ IActionResult
Návratový IActionResult typ je vhodný, pokud je možné v akci provést více ActionResult
návratových typů. Typy ActionResult
představují různé stavové kódy HTTP. Každá ne abstraktní třída odvozená z ActionResult
kvalifikuje 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 atribut liberalně [ProducesResponseType]
. Tento atribut vytvoří 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_IActionResult(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? NotFound() : 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
, pokud produkt existuje. Metoda Ok pohodlí je vyvolána jako zkratka proreturn new OkObjectResult(product);
.
Asynchronní akce
Vezměte v úvahu 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_IActionResult(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
return CreatedAtAction(nameof(GetById_IActionResult), new { id = product.Id }, product);
}
V předchozí akci:
Stavový kód 400 se vrátí, když popis produktu obsahuje "XYZ Widget". 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. Následující kód je alternativou k volání
CreatedAtAction
:return new CreatedAtActionResult(nameof(GetById), "Products", new { id = product.Id }, product);
V předchozí cestě
Product
kódu je objekt zadaný v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Následující model například označuje, že požadavky musí obsahovat vlastnosti Name
a Description
vlastnosti. Neúspěšné zadá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; } = string.Empty;
[Required]
public string Description { get; set; } = string.Empty;
public bool IsOnSale { get; set; }
}
[ApiController]
Pokud se atribut použije, výsledkem chyb ověření modelu je stavový kód 400. Další informace naleznete v tématu Automatické odpovědi HTTP 400.
ActionResult vs IActionResult
Následující část porovnává s ActionResult
IActionResult
Typ ActionResult<T>
ASP.NET Core obsahuje návratový typ ActionResult<T> pro akce kontroleru webového rozhraní API. Umožňuje vrácení typu odvozeného z ActionResult konkrétního typu nebo vrácení určitého typu. ActionResult<T>
nabízí následující výhody oproti typu IActionResult:
[ProducesResponseType]
Vlastnost atributuType
lze vyloučit. Například[ProducesResponseType(200, Type = typeof(Product))]
je zjednodušena na[ProducesResponseType(200)]
. Očekávaný návratový typ akce je odvozen z hodnotyT
inActionResult<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í. Vstupní parametr akce může například 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_ActionResultOfT(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? NotFound() : 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_ActionResultOfT(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
return CreatedAtAction(nameof(GetById_ActionResultOfT), new { id = product.Id }, product);
}
V předchozí akci:
- Stavový kód 400 (BadRequest) vrací 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 je generován metodou CreatedAtAction při vytvoření produktu. V této cestě
Product
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Typ HttpResults
Kromě předdefinovaných typů výsledků MVC (IActionResult a ActionResult<T>) ASP.NET Core obsahuje typy HttpResults , které je možné použít v minimálních rozhraních API i webovém rozhraní API.
Jiné než typy výsledků specifické pro MVC:HttpResults
Jsou implementace výsledků, která je zpracována voláním IResult.ExecuteAsync.
Nevyužít nakonfigurované formátovací moduly. Využití nakonfigurovaných formátovacích nástrojů znamená:
- Některé funkce, jako
Content negotiation
jsou, nejsou dostupné. Content-Type
Produkce je určena implementacíHttpResults
.
- Některé funkce, jako
To HttpResults
může být užitečné při sdílení kódu mezi minimálními rozhraními API a webovým rozhraním API.
Typ IResult
Obor Microsoft.AspNetCore.Http.HttpResults názvů obsahuje třídy, které implementují IResult rozhraní. Rozhraní IResult
definuje kontrakt, který představuje výsledek koncového bodu HTTP. Static Results třída slouží k vytvoření různých IResult
objektů, které představují různé typy odpovědí.
Tabulka předdefinovaných výsledků zobrazuje běžné pomocné rutiny výsledků.
Uvažujte následující kód:
[HttpGet("{id}")]
[ProducesResponseType(typeof(Product), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IResult GetById(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? Results.NotFound() : Results.Ok(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, vygenerovaný results.ok <T>().
Uvažujte následující kód:
[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(Product), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IResult> CreateAsync(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return Results.BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
var location = Url.Action(nameof(GetById), new { id = product.Id }) ?? $"/{product.Id}";
return Results.Created(location, product);
}
V předchozí akci:
- Stavový kód 400 se vrátí, když:
- Atribut
[ApiController]
byl použit a ověření modelu selže. - Popis produktu obsahuje "XYZ Widget".
- Atribut
- Stavový kód 201 je generován metodou
Results.Create
při vytvoření produktu. V této cestěProduct
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Výsledky<TResult1, typ TResultN>
Static TypedResults třída vrací konkrétní IResult
implementaci, která umožňuje použít IResult
jako návratový typ. Použití konkrétní IResult
implementace nabízí následující výhody oproti typu IResult:
[ProducesResponseType]
Všechny atributy lze vyloučit, protožeHttpResult
implementace přispívá automaticky k metadatům koncového bodu.
Pokud je potřeba více IResult
návratových typů, je vrácení Results<TResult1, TResultN>
upřednostňované před vrácením IResult
. Results<TResult1, TResultN>
Vrácení se upřednostňuje, protože obecné typy sjednocení automaticky uchovávají metadata koncového bodu.
Typy Results<TResult1, TResultN>
sjednocení implementují implicitní operátory přetypování, aby kompilátor mohl automaticky převést typy zadané v obecných argumentech na instanci sjednocovacího typu. To má přidanou výhodu poskytování kontroly času kompilace, že obslužná rutina trasy skutečně vrací pouze výsledky, které deklaruje. Pokus o vrácení typu, který není deklarován jako jeden z obecných argumentů, aby výsledkem Results<>
byla chyba kompilace.
Uvažujte následující kód:
[HttpGet("{id}")]
public Results<NotFound, Ok<Product>> GetById(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? TypedResults.NotFound() : TypedResults.Ok(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, vygenerovaný TypedResults.Ok <T>.
[HttpPost]
public async Task<Results<BadRequest, Created<Product>>> CreateAsync(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return TypedResults.BadRequest();
}
_productContext.Products.Add(product);
await _productContext.SaveChangesAsync();
var location = Url.Action(nameof(GetById), new { id = product.Id }) ?? $"/{product.Id}";
return TypedResults.Created(location, product);
}
V předchozí akci:
- Stavový kód 400 se vrátí, když:
- Atribut
[ApiController]
byl použit a ověření modelu selže. - Popis produktu obsahuje "XYZ Widget".
- Atribut
- Stavový kód 201 je generován metodou
TypedResults.Create
při vytvoření produktu. V této cestěProduct
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Další materiály
Zobrazení nebo stažení ukázkového kódu (postup stažení)
ASP.NET Core nabízí následující možnosti návratových typů 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 komplexní datový typ (například string
vlastní typ objektu). Představte si následující akci, která vrací kolekci vlastních Product
objektů:
[HttpGet]
public List<Product> Get() =>
_repository.GetProducts();
Bez známých podmínek pro ochranu před provedením akce může být vrácení konkrétního typu dostačující. 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átit 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 jejich zápisem do odpovědi. Zvažte deklaraci návratového typu podpisu akce, který IAsyncEnumerable<T> zaručuje asynchronní iteraci. V konečném důsledku je režim iterace založen na vráceného podkladového konkrétního typu. MVC automaticky do vyrovnávací paměti jakéhokoli konkrétního typu, který implementuje IAsyncEnumerable<T>
.
Vezměte v úvahu následující akci, která vrací záznamy o produktech s cenami prodeje 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 možné v akci provést více ActionResult
návratových typů. Typy ActionResult
představují různé stavové kódy HTTP. Každá ne abstraktní třída odvozená z ActionResult
kvalifikuje 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 atribut liberalně [ProducesResponseType]
. Tento atribut vytvoří 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
, pokud produkt existuje. Metoda Ok pohodlí je vyvolána jako zkratka proreturn new OkObjectResult(product);
.
Asynchronní akce
Vezměte v úvahu 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 "XYZ Widget". 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 poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Následující model například označuje, že požadavky musí obsahovat vlastnosti Name
a Description
vlastnosti. Neúspěšné zadá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; }
}
[ApiController]
Pokud se atribut použije, výsledkem chyb ověření modelu je stavový kód 400. Další informace naleznete v tématu Automatické odpovědi HTTP 400.
ActionResult vs IActionResult
Následující část porovnává s ActionResult
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:
[ProducesResponseType]
Vlastnost atributuType
lze vyloučit. Například[ProducesResponseType(200, Type = typeof(Product))]
je zjednodušena na[ProducesResponseType(200)]
. Očekávaný návratový typ akce se místo toho odvodí 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í. Vstupní parametr akce může například 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) vrací 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 je generován metodou CreatedAtAction při vytvoření produktu. V této cestě
Product
kódu je objekt poskytován v textu odpovědi.Location
Je k dispozici hlavička odpovědi obsahující nově vytvořenou adresu URL produktu.
Další materiály
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro