简体   繁体   English

Owin Middleware中的MVC错误处理

[英]MVC error handling in Owin Middleware

When certain exceptions are thrown in controllers, I want to catch those exceptions and do some extra logic. 当控制器中抛出某些异常时,我想捕获这些异常并做一些额外的逻辑。

I was able to achieve this with a custom IExceptionFilter that is added to the global filters list. 我能够使用添加到全局筛选器列表的自定义IExceptionFilter来实现此目的。

However, I preffer to handle these exception within a custom Owin middleware. 但是,我希望在自定义Owin中间件中处理这些异常。 My middleware looks like this: 我的中间件看起来像这样:

      try
        {

            await Next.Invoke(context);
        }
        catch (AdalSilentTokenAcquisitionException e)
        {
           //custom logic
        }

This piece of code does not work, it looks like the exception is already catched and handled in MVC. 这段代码不起作用,看起来异常已经在MVC中被捕获和处理。 Is there a way to skip the exception processing from MVC and let the middleware catch the exception? 有没有办法跳过MVC的异常处理,让中间件捕获异常?

Update: I've found a cleaner approach, see my updated code below. 更新:我找到了更清洁的方法,请参阅下面的更新代码。 With this approach, you don't need a custom Exception Filter and best of all, you don't need the HttpContext ambient service locator pattern in your Owin middleware. 使用这种方法,您不需要自定义的异常过滤器,最重要的是,您不需要Owin中间件中的HttpContext环境服务定位器模式。

I have a working approach in MVC, however, somehow it doesn't feel very comfortable, so I would appreciate other people's opinion. 我在MVC中有一个工作方法,然而,不知何故它感觉不舒服,所以我会感谢其他人的意见。

First of all, make sure there are no exception handlers added in the GlobalFilters of MVC. 首先,确保MVC的GlobalFilters中没有添加异常处理程序。

Add this method to the global asax: 将此方法添加到全局asax:

    protected void Application_Error(object sender, EventArgs e)
    {
        var lastException = Server.GetLastError();
        if (lastException != null)
        {
            HttpContext.Current.GetOwinContext().Set("lastException", lastException);
        }
    }

The middleware that rethrows the exception 重新抛出异常的中间件

public class RethrowExceptionsMiddleware : OwinMiddleware
{
    public RethrowExceptionsMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        await Next.Invoke(context);
        var exception = context.Get<Exception>("lastException");
        if (exception != null)
        {
            var info = ExceptionDispatchInfo.Capture(exception);
            info.Throw();
        }
    }
}

There's no perfect way to do this (that I know of), but you can replace the default IExceptionHandler with one that just passes the error through to the rest of the stack. 没有完美的方法可以做到这一点(我知道),但您可以将默认的IExceptionHandler替换为只将错误传递给堆栈其余部分的IExceptionHandler

I did some extensive digging about this, and there really doesn't seem to be a better way for now. 我对此进行了大量的挖掘 ,现在似乎没有更好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM