【问题标题】:ASP.NET Web API - return CLR object or HttpResponseMessageASP.NET Web API - 返回 CLR 对象或 HttpResponseMessage
【发布时间】:2012-09-04 22:55:44
【问题描述】:

对于来自操作方法的返回类型,Web API 中的一般做法是什么?

像这样返回 CLR 对象:

public IEnumerable<ContactModel> Get()
{
    return _contactService.GetAllForUser();
}

或者将您的对象包装在HttpResponseMessage

public HttpResponseMessage Get()
{
    IEnumerable<ContactModel> contacts = _contactService.GetAllForUser();

    return Request.CreateResponse((HttpStatusCode) 200, contacts);
}

我更喜欢使用我自己的 CLR 对象作为返回类型,因为它显然会产生更简洁的方法,因为您不必每次都实例化 HttpResponseMessage

【问题讨论】:

  • AFAIK,如果您返回 CRL 类型,如果出现异常,异常消息会传播到客户端,这不是一个好习惯。
  • 显然不是——但看看@Claudio 的回答,他建议您可以使用 HttpResponseException 捕获异常并向客户端返回适当的响应

标签: c# .net asp.net-web-api


【解决方案1】:

这里重要的一点是,这个选择是一个偏好的问题。如果您正在创建一个“URI 样式”HTTP api,其中返回类型是客户端预先知道的,那么这可能是您的首选方法。

但是,就我个人而言,我不喜欢返回 CLR 类型。我相信,通过这种方法,您可能会失去 HTTP 的许多好处。我总是返回 HttpResponseMessage。

如果您考虑标准过程调用,则有两种可能的结果,即返回返回类型或出现异常。由于重定向、临时不可用的服务器、无内容、未修改、服务器连接、首选标头变体等,HTTP 交互要灵活得多。

我认为 ApiController 类是您的应用程序有机会将面向对象的方法调用映射到 HTTP 请求/响应的地方。我认为明确地进行这种映射有助于利用 HTTP。让框架神奇地将 CLR 类型转换为某种有线表示,确实节省了一些输入,但它掩盖了正在发生的事情,并迫使您通过 ActionFilters 和 MessageHandlers 间接进行任何类型的 HTTP 交互。

我没有兴趣说服愿意返回 CLR 类型进行更改的人,我只是想再次向喜欢返回 HttpResponseMessage 想法的人保证,尽管您不会看到,但这是一个完全可行的选择很多这样的样本。

【讨论】:

  • +1 使用 HttpResponseMessage 的一个好处是,您可以在错误请求或服务器错误的情况下返回“错误类型”,而不必尝试将错误附加到空的 CLR 对象因为你被绑定到那个特定的返回类型。
  • 我只是创建了一个通用的 ReturnMessages 类,它有一个包含 CLR 对象的 ReturnClass 值。此类还包含返回代码、返回消息和任何相关数据,以防万一发生意外。这样,我可以为所有消息返回相同的类,而不是在使用它时检查类型。
  • @user3241191 将元数据添加到返回正文中是多余的。 HTTP 标头旨在将元数据添加到消息中。发明自己的元数据约定是浪费精力,并且会在需要时严重限制您与其他系统集成的能力。
  • 它将如何严重限制我与其他系统集成的能力?它基本上是在吐出一个 json 样式的对象,该对象在所有 API 返回中都是一致的。因此,消费代码实际上只需要编写一次,并且可以全面重复使用。如果系统可以与 JSON 样式返回的对象进行交互,那么实际上并没有严重的限制。
  • @user3241191 信不信由你,并非网络上的所有系统都使用 json。您将如何向发送accept: text/plain 的客户返回响应?
【解决方案2】:

我认为第一个选项是最好的。在任何情况下,如果没有错误,则返回码将为 200,无需您进行任何设置。

如果有任何异常,您可以使用适当的代码和消息抛出 HttpResponseException

throw new HttpResponseException(
    Request.CreateResponse<string>(HttpStatusCode.BadRequest, 'Your message'))

【讨论】:

  • 我试过以这种方式从我的操作方法中抛出一个 HttpResponseException,但我似乎只是在客户端上得到一个空的 200 响应?
  • 不应该这样。我自己做这个并且按预期工作。请仔细检查您的逻辑。
  • 啊,是的,它确实有效,我上次尝试时一定是做错了什么
  • 还有一件事 - 如果我像这样抛出 HttpResponseException: throw new HttpResponseException(Request.CreateResponse((HttpStatusCode)401, "Unauthorized msg")) - 响应正文为空。如何在正文中添加消息?
  • @ClaudioRedi 为什么您认为选项 1 比选项 2“更好”?
猜你喜欢
  • 1970-01-01
  • 2013-04-01
  • 2015-02-21
  • 2017-04-13
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2017-07-02
相关资源
最近更新 更多