查看或下載示例代碼()
ASP.NET Core為 Web API 控制器操作返回類型提供以下選項:
本文介紹何時最適合使用每個返回類型。
特定類型
最基本的操作返回基元或復雜數(shù)據(jù)類型,例如, 或自定義對象。 請參考以下操作,該操作返回自定義 對象的集合:
[HttpGet]
public Task> Get() =>
_productContext.Products.OrderBy(p => p.Name).ToListAsync();
如果沒有已知條件來防范,則返回特定類型可能足夠。 上述操作不接受任何參數(shù),因此不需要參數(shù)約束驗證。
如果存在多種返回類型,通常會將 返回類型與基元或復雜返回類型混合。 要支持此類操作,必須使用 或 。 本文提供了多個返回類型的多個示例。
返回 或
ASP.NET Core緩沖在將操作寫入響應之前返回的操作的結果。 請考慮將操作簽名的返回類型聲明為 保證異步迭代。 最終,迭代模式基于返回的基礎具體類型,并且所選格式化程序會影響處理結果的方式:
請考慮以下操作,該操作將銷售價格的產(chǎn)品記錄返回為
:
[HttpGet("syncsale")]
public IEnumerable GetOnSaleProducts()
{
var products = _productContext.Products.OrderBy(p => p.Name).ToList();
foreach (var product in products)
{
if (product.IsOnSale)
{
yield return product;
}
}
}
上述操作的
等效項為:
[HttpGet("asyncsale")]
public async IAsyncEnumerable GetOnSaleProductsAsync()
{

var products = _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable();
await foreach (var product in products)
{
if (product.IsOnSale)
{
yield return product;
}
}
}
類型
當操作中可能有多個 返回類型時,適合使用 返回類型。 類型表示多種 HTTP 狀態(tài)代碼。 派生自 的任何非抽象類都限定為有效的返回類型。 此類別中的某些常見返回類型為 (400)、 (404) 和 (200)。 或者,可以使用 類中的便利方法從操作返回 類型。 例如, (); 是 new (); 的簡寫形式。
由于此操作類型中有多個返回類型和路徑,因此必須自由使用 [] 特性。 此特性可針對 等工具生成的 Web API 幫助頁生成更多描述性響應詳細信息。 [] 指示操作將返回的已知類型和 HTTP 狀態(tài)代碼。
同步操作
請參考以下同步操作,其中有兩種可能的返回類型:
[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);
}
在上述操作中:
異步操作
請參考以下異步操作,其中有兩種可能的返回類型:
[HttpPost()]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task 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);
}
在上述操作中:
例如,以下模型指明請求必須包含 Name 和 屬性。 未在請求中提供 Name 和 會導致模型驗證失敗。
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; }
}
如果應用了該 [] 屬性,則模型驗證錯誤會導致 400 狀態(tài)代碼。 有關詳細信息,請參閱。
與
以下部分比較 和
類型
ASP.NET Core包括 Web API 控制器操作的 返回類型。 它允許返回派生 自或返回 。 在 上提供以下優(yōu)勢:
C# 不支持對接口使用隱式強制轉(zhuǎn)換運算符。 因此,必須使用 ,才能將接口轉(zhuǎn)換為具體類型。 例如,在下面的示例中,使用 不起作用:
[HttpGet]
public ActionResult> Get() =>
_repository.GetProducts();

上面代碼的一種修復方法是返回 .().();。
大多數(shù)操作具有特定返回類型。 執(zhí)行操作期間可能出現(xiàn)意外情況,不返回特定類型就是其中之一。 例如,操作的輸入?yún)?shù)可能無法通過模型驗證。 在此情況下,通常會返回相應的 類型,而不是特定類型。
同步操作
請參考以下同步操作,其中有兩種可能的返回類型:
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult GetById_ActionResultOfT(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? NotFound() : product;
}
在上述操作中:
異步操作
請參考以下異步操作,其中有兩種可能的返回類型:
[HttpPost()]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task> 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);
}
在上述操作中:
在創(chuàng)建產(chǎn)品后action是設置返回信息的顯示方式, 方法生成 201 狀態(tài)代碼。 在此代碼路徑中,將在響應正文中提供 對象。 提供了包含新建產(chǎn)品 URL 的 響應標頭。 類型
除了特定于 MVC 的內(nèi)置結果類型 (和 ) ,ASP.NET Core還包括可在最小 API 和 Web API 中使用的 類型。
不同于 MVC 特定的結果類型,包括 :
在最小 API 和 Web API 之間共享代碼時,這 非常有用。
類型
命名空間 ..Http. 包含實現(xiàn)接口的 類。 接口 定義一個表示 HTTP 終結點結果的協(xié)定。 靜態(tài) 類用于創(chuàng)建各種 對象,這些對象表示不同類型的響應。
表顯示常見的結果幫助程序。
考慮下列代碼:
[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);
}
在上述操作中:
考慮下列代碼:
[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(Product), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task 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);
}
在上述操作中:
在創(chuàng)建產(chǎn)品后,. 方法生成 201 狀態(tài)代碼。 在此代碼路徑中action是設置返回信息的顯示方式,將在響應正文中提供 對象。 提供了包含新建產(chǎn)品 URL 的 響應標頭。結果 類型
靜態(tài) 類返回允許用作返回類型的具體實現(xiàn)。 具體 實現(xiàn)的使用比 具有以下優(yōu)勢:
如果需要多個 返回類型,則返回 優(yōu)先于返回 。 返回 是首選,因為泛型聯(lián)合類型會自動保留終結點元數(shù)據(jù)。
聯(lián)合類型實現(xiàn)隱式強制轉(zhuǎn)換運算符,以便編譯器可以自動將泛型參數(shù)中指定的類型轉(zhuǎn)換為聯(lián)合類型的實例。 這增加了提供編譯時檢查的好處,即路由處理程序?qū)嶋H上只返回聲明路由處理程序的結果。 嘗試返回未聲明為泛型參數(shù) 之一的類型,導致編譯錯誤。
考慮下列代碼:
[HttpGet("{id}")]
public Results> GetById(int id)
{
var product = _productContext.Products.Find(id);
return product == null ? TypedResults.NotFound() : TypedResults.Ok(product);
}
在上述操作中:
[HttpPost]
public async Task>> 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);
}
在上述操作中:
在創(chuàng)建產(chǎn)品后,. 方法生成 201 狀態(tài)代碼。 在此代碼路徑中,將在響應正文中提供 對象。 提供了包含新建產(chǎn)品 URL 的 響應標頭。其他資源