返回IHttpActionResult与IEnumerable<;项目>;vs IQueryable<;项目

本文关键字:项目 lt vs IQueryable gt IHttpActionResult 返回 IEnumerable | 更新日期: 2023-09-27 17:59:07

在ASP中。NET Web API 2,以下两者之间有什么区别?

public async Task<IEnumerable<MyItem>> GetMyItems()
{
    //... code ..., var myItems = await ...
    return myItems;
}

public async Task<IQueryable<MyItem>> GetMyItems()
{
    //... code ..., var myItems = await ...
    return myItems;
}

public async Task<IHttpActionResult> GetMyItems()
{
    //... code ..., var myItems = await ...
    return Ok(myItems);
}

我应该返回IHttpActionResult还是IEnumerable<MyItem>/IQueryable<MyItem>

返回IHttpActionResult与IEnumerable<;项目>;vs IQueryable<;项目

您应该返回IHttpActionResult,因为您可以更具体地针对客户端。您可以创建更用户友好的web应用程序。基本上,您可以针对不同的情况返回不同的HTML状态消息。

例如:

public async Task<IHttpActionResult> GetMyItems()
{
    if(!authorized)
        return Unauthorized();
    if(myItems.Count == 0)
        return NotFound();
    //... code ..., var myItems = await ...
    return Ok(myItems);
}

IEnumerableIQueryable只会将数据解析为输出格式,您将没有正确的方法来处理异常。这是最重要的区别。

我会在IEnumerable和IHttpActionResult之间进行选择,您可以用稍微不同的方式对这两者做几乎相同的事情。IQueryable通常用于较低级别的数据访问任务和sql查询的延迟执行,所以我会将其封装在数据访问类中,而不使用web api公开它。

以下是来自http://www.asp.net/web-api/overview/web-api-routing-and-actions/action-results:

IHttpActionResult

Web API 2中引入了IHttpActionResult接口。本质上,它定义了一个HttpResponseMessage工厂。以下是使用IHttpActionResult接口的一些优点(相对于HttpResponseMessage类):

  • 简化控制器的单元测试
  • 将用于创建HTTP响应的通用逻辑移动到单独的类中
  • 通过隐藏构造响应的低级细节,使控制器操作的意图更加清晰

IEnumerable<项目>

对于所有其他返回类型,Web API使用媒体格式化程序来序列化返回值。Web API将序列化的值写入响应主体。响应状态代码为200(正常)。

public class ProductsController : ApiController
{
    public IEnumerable<Product> Get()
    {
        return GetAllProductsFromDB();
    }
}

这种方法的缺点是不能直接返回错误代码,例如404。但是,您可以为错误代码抛出HttpResponseException。了解更多信息。

如果您来到这里,您可能正在寻找如何返回错误状态代码,而不是返回IEumerable的API中的实际数据。

答案是,抛出一个HttpResponseException。这样就不需要使用ActionResult,因为它会把原本干净的代码搞得一团糟。

以下是文档中的完整示例:

var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
    {
        Content = new StringContent(string.Format("No product with ID = {0}", id)),
        ReasonPhrase = "Product ID Not Found"
    };
    throw new HttpResponseException(resp);

这个答案的功劳归于上面的@JasonWatmore。这只是为了让这个提示更加清晰,因为它非常有用。