【问题标题】:Equivalent of HttpResponseException/IHttpActionResponse for .net Core webapi 2 (not mvc).net Core web api 2(不是 mvc)的 HttpResponseException/IHttpAction 响应的等效项
【发布时间】:2018-04-18 22:08:52
【问题描述】:

当我阅读 webapi 以响应请求和处理错误时,一切都基于:

IHttpActionResult
HttpResponseException

但是当您创建一个 .net 核心 webapi 项目时,这些是不可用的。可以找到IActionResult,好像是等价的?

但我正在兜圈子试图找出一个非常简单的事情,那就是如何处理 .net 核心 webapi 中的错误,因为 HttpResponseException 不可用。我的印象是所有带有“http”的东西,只是为了一个完整的 MVC 应用程序。

我只想返回一个错误,肯定很简单...

【问题讨论】:

    标签: c# asp.net-core asp.net-core-webapi


    【解决方案1】:

    IActionResult 相当于IHttpActionResult,正如您所建议的那样。这是 ASP.NET Core MVC 中所谓的 MVC 和 Web API 整合的一部分。

    至于HttpResponseException,在 ASP.NET Core 中已完全删除。在 GitHub 上有一个有趣的 issue,其中 David Fowler 解释了为什么会这样:

    只是经典的“我们不希望人们将异常用于控制流”范例。人们做了一些事情,比如从他们的业务逻辑中使用它,这是各种各样的错误。我无法谈论性能问题,因为我没有测量,但抛出一个旨在被捕获以获取一些数据的异常比仅仅返回该结果更糟糕。

    建议的替代方法是使用各种 IActionResult 实现来创建 JSON 响应、返回错误等。同样,来自问题:

    我的建议是让操作方法返回 IActionResult(或异步变体)。

    IActionResult 和 object 都被支持的原因是它们各自适合不同的目的和不同的风格。对于一些最简单的情况,使用对象很好,但它一点也不强大。对于完全控制,有 IActionResult,它遵循众所周知的“命令模式”。

    IActionResult 模式允许控制器明确说明操作的结果应该发生什么:某种错误代码、重定向、序列化数据对象、渲染视图等。

    如果您希望在控制器之外处理错误,您可能会受益于阅读有关此主题的docs,其中详细介绍了使用中间件或过滤器进行错误处理。在 cmets 中,有一个指向 tutorial 的链接更详细地解释了错误处理的某些方面。

    为了完整起见,这里是中间件方法教程中的代码:

    app.UseExceptionHandler(
     options => {
        options.Run(
        async context =>
        {
          context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
          context.Response.ContentType = "text/html";
          var ex = context.Features.Get<IExceptionHandlerFeature>();
          if (ex != null)
          {
            var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace }";
            await context.Response.WriteAsync(err).ConfigureAwait(false);
          }
        });
     }
    );
    

    还有更多关于IExceptionFilter 方法的详细信息,但我不会在这里重复所有这些。

    【讨论】:

    • 但是,void 返回方法呢,例如PUT 和 POST?
    • PUT 和 POST 不需要是 void - 您仍然可以使用 IActionResult 并返回例如NoContent()Ok()。第一个给出 204,第二个给出 200。
    • 当我的代码被捕获或出错时如何返回 500 状态码,有什么建议吗?
    • 如果你想在控制器中处理异常,你可以使用StatusCode(500)
    • "人们做了一些事情,比如在他们的业务逻辑中使用它,这是各种各样的错误。" :facepalm: :cry: 但值得强调。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 2020-06-03
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多