2016-11-23 70 views
2

当某些异常在控制器中抛出时,我想捕获这些异常并执行一些额外的逻辑。Owin Middleware中的MVC错误处理

我可以通过添加到全局过滤器列表的自定义IExceptionFilter实现此目的。

但是,我主张在自定义的Owin中间件中处理这些异常。 我中间件是这样的:

 try 
     { 

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

这段代码不能正常工作,它看起来像异常已经获取,并在MVC处理。 有没有办法跳过MVC的异常处理,并让中间件捕获异常?

+0

的[在ASP.NET如何禁用\ *所有\ *异常处理可能的复制Web API 2(为我自己腾出空间)?](http://stackoverflow.com/questions/34201527/how-do-i-disable-all-exception-handling-in-asp-net-web-api- 2-to-make-room-for) –

+0

不重复 - 另一个问题是关于Web API 2,这是关于MVC框架的。部分答案(OWIN中间件)适用,但关闭默认错误处理的机制不同。 –

回答

2

没有完美这样做的方式(我知道的),但是你可以用默认的IExceptionHandler代替,只是将错误传递给堆栈的其余部分。

对此我做了some extensive digging,现在确实似乎没有更好的方法。

+0

另请参阅http://stackoverflow.com/questions/34201527/how-do-i-disable-all-exception-handling-in-asp-net-web-api-2-to-make-room-for –

+0

感谢您的回复,但是我使用MVC而不是Web Api,所以我更换了 config.Services.Replace(typeof(IExceptionHandler),new MyExceptionHandler()); 与 GlobalFilters.Filters.Add(new MyExceptionHandler()); 这样,异常不在中间件中处理......我应该如何在MVC中配置MyExceptionHandler? – Identity

+0

@Identity:在ASP.NET核心1.0中的MVC?或者像在核心前的MVC框架? –

1

更新:我发现一个更清洁的方法,请参阅下面我更新的代码。 使用这种方法,您不需要自定义的Exception Filter,最重要的是,您不需要Owin中间件中的HttpContext环境服务定位器模式。

我有一个MVC的工作方法,但是,不知何故,它感觉不舒服,所以我会很感激别人的意见。

首先,确保在MVC的GlobalFilters中没有添加异常处理程序。

此方法添加到全球ASAX:

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

是重新抛出异常的中间件

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(); 
     } 
    } 
}