异常处理 ASP.NET MVC Web API [英] Exception Handling ASP.NET MVC Web API

查看:29
本文介绍了异常处理 ASP.NET MVC Web API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,是的,我们已经创建并正在使用从 ExceptionFilterAttribute 继承的异常过滤器.它在我们的身份过滤器之后立即在应用启动时的配置中注册,并且如果我们的 API 内某处发生错误,它几乎可以正常工作.

I'll start off with, yes, we have created and are using an exception filter inheriting from the ExceptionFilterAttribute. It is registered in the config on app startup right after our identity filter and works pretty much as expected if an error occurs somewhere inside our API.

话虽如此,我正在寻找一种方法来处理在到达 API 之前发生的错误.

That being said, I'm looking for a way to handle errors that happen before it reaches the API.

推理:我们永远不想返回 YSOD 和/或 IIS HTML 错误.我们总是希望点击自定义异常过滤器/处理程序,以便我们可以正确处理日志记录并向用户返回 JSON 响应.

Reasoning: We never want to return a YSOD and/or IIS HTML error. We ALWAYS want to hit a custom exception filter/handler so that we can handle logging correctly and return a JSON response to the user.

截至目前,使用 Fiddler 发出请求,我可以附加到 w3wp.exe 进程并查看请求命中 global.asax 中的 Application_BeginRequest 方法.之后,它只返回一个 500 响应.它永远不会因异常而中断代码,也不会在此之后达到我的任何断点.它似乎正在返回一个 IIS 错误.我们绝不希望这种情况发生.我们需要能够捕获所有这些低级"异常、记录它们并返回对用户有意义的内容.

As of right now, using Fiddler to make a request, I can attach to the w3wp.exe process and see the request hit the Application_BeginRequest method in the global.asax. After that, it just returns a 500 response. It never breaks in code with an exception or hits any of my break points after that. It seems to be returning an IIS error. We never want this to happen. We need the ability to catch all of these "low-level" exceptions, log them, and return something meaningful to the user.

我们可以做些什么来处理之前的错误,ASP.NET MVC Web API 代码似乎受到了什么影响?

Is there something we can do to handle errors before, what seems to be hitting the ASP.NET MVC Web API code?

推荐答案

虽然我喜欢 Darin 的回答,但它在我们的案例中不起作用,因为 ASP.NET MVC Web API 框架在内部抑制/处理异常而不是重新抛出在 Global.asax 中点击 Application_Error 方法.我们的解决方案是这样的.

Albeit I like Darin's answer it doesn't work in our case since the ASP.NET MVC Web API framework is suppressing/handling exceptions internally and not re-throwing to hit the Application_Error method in the Global.asax. Our solution is this.

我最终像这样创建了一个自定义 DelegatingHandler:

I ended up creating a custom DelegatingHandler like so:

public class PrincipalHandler : DelegatingHandler
{
    protected const string PrincipalKey = "MS_UserPrincipal";
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        setAnonymousPrincipal();

        request = InitializeIdentity(request);

        return base.SendAsync(request, cancellationToken)
            .ContinueWith(r =>
                              {
                                  // inspect result for status code and handle accordingly
                                  return r.Result;
                              });
    }
}

然后我将它插入到 HttpConfiguration 中,以确保它是第一个/最后一个被命中的处理程序.处理程序在 Web API 中的工作方式是分层的.因此,每个请求要命中的第一个处理程序将是响应命中的最后一个处理程序.至少这是我的理解,如果我错了,请随时纠正我.

I then inserted it into the HttpConfiguration to make sure it is the first/last handler to be hit. The way handlers work in the Web API is in a hierarchical fashion. So the first handler to be hit per request, will be the last handler to be hit on the response. At least this is my understanding, someone feel free to correct me if I'm wrong.

public static void ConfigureApis(HttpConfiguration config)
{
    config.MessageHandlers.Insert(0, new PrincipalHandler());
}

通过使用这种方法,我们现在可以检查从 Web API 和控制器的任何响应中返回的每个结果.这使我们能够处理由于某些内容未按预期返回而可能需要发生的任何日志记录.我们现在还可以更改返回的响应内容,以便 IIS 在看到某些 HTTP 状态代码时不会插入任何默认 HTML 错误页面.

By using this approach we can now inspect every result coming back in any response from the web API and controllers. This allows us to handle any logging that may need to occur as a result of something not being returned as we expect. We can now also alter the content of the response coming back so that IIS doesn't insert any default HTML error pages if it sees certain HTTP status codes.

我唯一遇到的问题,我希望他们在即将发布的 Web API 中更改它,是他们没有在从 base.SendAsync() 返回的任务上发送异常备份.所以我们唯一需要通过的信息就是HTTP状态码,并尽力给消费者一个合理或可能的答案.

The only problem I have with this, and I'm hoping they change it in an upcoming release of the web API, is that they aren't sending the exception back up on the Task being returned from base.SendAsync(). So the only information we have to go by is the HTTP status code and try our best to give a reasonable or probable answer to the consumer.

这篇关于异常处理 ASP.NET MVC Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆