Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# OWIN/Katana的未处理异常全局处理程序?_C#_Asp.net Web Api_Exception Handling_Owin_Katana - Fatal编程技术网

C# OWIN/Katana的未处理异常全局处理程序?

C# OWIN/Katana的未处理异常全局处理程序?,c#,asp.net-web-api,exception-handling,owin,katana,C#,Asp.net Web Api,Exception Handling,Owin,Katana,在Katana(OWIN)实现中实现全局异常捕捉器处理程序的正确方法是什么 在作为Azure云服务(工作者角色)运行的自托管OWIN/Katana实现中,我将以下代码放置在中间件中: throw new Exception("pooo"); public class GlobalExceptionMiddleware : OwinMiddleware { public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)

在Katana(OWIN)实现中实现全局异常捕捉器处理程序的正确方法是什么

在作为Azure云服务(工作者角色)运行的自托管OWIN/Katana实现中,我将以下代码放置在中间件中:

throw new Exception("pooo");
public class GlobalExceptionMiddleware : OwinMiddleware
{
   public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)
   {}

   public override async Task Invoke(IOwinContext context)
   {
      try
      {
          await Next.Invoke(context);
      }
      catch(Exception ex)
      {
          // your handling logic
      }
   }
 }
public class Startup
{
    public void Configuration(IAppBuilder builder)
    {
        var config = new HttpConfiguration();

        builder.Use<GlobalExceptionMiddleware>();
        //register other middlewares
    }
}
然后,我将此代码放在Startup类配置方法中,在事件处理程序中设置断点:

 AppDomain.CurrentDomain.UnhandledException += 
    CurrentDomain_UnhandledExceptionEventHandler;
和同一类中的事件处理程序(第一行设置了断点):

当代码运行时,不会命中断点。但是,Visual Studio输出窗口确实包含以下内容:

A first chance exception of type 'System.Exception' occurred in redacted.dll
A first chance exception of type 'System.Exception' occurred in mscorlib.dll
我还尝试将wireup和handler移动到Worker角色OnStart方法,但仍然没有命中断点

我根本没有使用WebAPI,但确实查看了关于在那里做了什么的帖子,但我没有发现任何明确的内容,所以我在这里

在.NET Framework 4.5.2上运行,与2013年相比

所有想法都受到赞赏。
谢谢。

尝试编写一个自定义中间件,并将其作为第一个中间件:

throw new Exception("pooo");
public class GlobalExceptionMiddleware : OwinMiddleware
{
   public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)
   {}

   public override async Task Invoke(IOwinContext context)
   {
      try
      {
          await Next.Invoke(context);
      }
      catch(Exception ex)
      {
          // your handling logic
      }
   }
 }
public class Startup
{
    public void Configuration(IAppBuilder builder)
    {
        var config = new HttpConfiguration();

        builder.Use<GlobalExceptionMiddleware>();
        //register other middlewares
    }
}
将其作为第一个
中间件:

throw new Exception("pooo");
public class GlobalExceptionMiddleware : OwinMiddleware
{
   public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)
   {}

   public override async Task Invoke(IOwinContext context)
   {
      try
      {
          await Next.Invoke(context);
      }
      catch(Exception ex)
      {
          // your handling logic
      }
   }
 }
public class Startup
{
    public void Configuration(IAppBuilder builder)
    {
        var config = new HttpConfiguration();

        builder.Use<GlobalExceptionMiddleware>();
        //register other middlewares
    }
}

@Khanh TO的回答非常好;很好的简洁代码,解释得很好

这对我不起作用。我向一个.NET MVC控制器添加了一个测试异常,如下所示:

throw new Exception("Test GlobalExceptionMiddleware");
protected override void OnException(ExceptionContext filterContext)
{
    if (filterContext.ExceptionHandled)
    {
        return;
    }
    var e = filterContext.Exception;
    Log.Error("BaseController.OnException caught exception:", e);
    filterContext.ExceptionHandled = true;
}
Invoke
方法中未捕获异常

这很容易调试:

  • 在测试异常上放置断点
  • 点击F10或在每一行上跨一步,直到找到处理异常的代码
  • 对我来说,有代码添加到
    BaseController
    覆盖
    OnException
    。此代码正在处理异常,而不是重新触发。我希望这是对@Khanh to答案的有益补充

    更新 好的,我意识到这个问题是用WebAPI标记的,我的用例是.NETMVC,但我在搜索Owin中间件时发现了这个问题。当我调试带有测试异常的解决方案,并在Locals视图中查看
    $exception
    时,当我回到Owin中间件时,异常就消失了。因此,我没有使用@Khanh TO答案中的代码。相反,我在我的Startup和Global.asax中添加了try/catch块。我的基本控制器中也有一个异常,如下所示:

    throw new Exception("Test GlobalExceptionMiddleware");
    
    protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled)
        {
            return;
        }
        var e = filterContext.Exception;
        Log.Error("BaseController.OnException caught exception:", e);
        filterContext.ExceptionHandled = true;
    }
    
    此答案将捕获应用程序启动时的任何异常以及控制器中的任何异常。这就足够满足我的需要了。

    试试这个:

    public class CustomExceptionHandler : IExceptionHandler
    {    
        public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
          // Perform some form of logging
    
          context.Result = new ResponseMessageResult(new HttpResponseMessage
          {
            Content = new StringContent("An unexpected error occurred"),
            StatusCode = HttpStatusCode.InternalServerError
          });
    
          return Task.FromResult(0);
        }
    }
    
    在启动时:

    public void Configuration(IAppBuilder app)
    {
      var config = new HttpConfiguration();
    
      config.Services.Replace(typeof(IExceptionHandler), new CustomExceptionHandler());
    }
    

    可以使用自定义异常过滤器属性

    public static class WebApiConfiguration
    {
        public static void Register(HttpConfiguration config)
        {
            config.RegisterExceptionFilters();
        }
    }
    
    public static class HttpConfigurationFilterExtensions
    {
        public static HttpConfiguration RegisterExceptionFilters(this HttpConfiguration httpConfig)
        {
            httpConfig.Filters.Add(new CustomExceptionFilterAttribute());
    
            return httpConfig;
        }
    }
    
    public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            if (context.Exception is CustomException)
            {
                context.Response = new HttpResponseMessage((HttpStatusCode)CustomHttpStatusCode.CustomCode);
            }
        }
    }
    
    public class CustomException : Exception
    {
        public CustomException(string message)
            : base(message)
        {
        }
    }
    

    那不行。默认情况下会处理Web API异常。代码将不会进入catch块。试试看。@Schizo博士:如果异常被web api捕获并吞没(这意味着web api已经完成了恢复)。这段代码肯定不会进入catch块,就像任何正常的异常处理代码一样。如果您在堆栈跟踪中捕获了一个异常,并且没有重新抛出它,那么堆栈跟踪上方的代码将不会捕获任何异常。这是预期的行为。@Schizo博士:
    Web API异常在默认情况下被处理
    =>这意味着异常被处理,因此它不会向上传播堆栈跟踪。这个全局中间件只处理
    未处理的
    异常,这使得它不处理
    已处理的
    异常(通过web api)非常有意义。对于任何未经处理(由其他中间件)抛出的异常或web api内部重新抛出的异常,该中间件应该能够捕获它们。我的假设是,如果我有一个控制器在调用其操作时抛出异常,我希望中间件(您已经描述)能够捕获该异常,并且实现能够执行它需要执行的任何操作,问题是中间件实际上没有进入catch块,因此没有意识到引发的异常,也没有出现在字典中。我是否误解了?@Khanh在我启动并运行的基本示例中,我有一个控制器和一个引发异常的操作。除了默认的WebAPI行为之外,没有任何地方可以处理这个问题,我相信它可以处理这个问题。因此,中间件不做任何事情。您必须替换web API中的全局异常处理程序,然后该中间件才能工作。请看我链接到的线程。这应该是答案。