捕获IIS级未处理的异常

时间:2020-04-30 07:21:18

标签: c# asp.net exception iis asp.net-web-api

我试图在一个ASP.NET Web API(不是核心)项目(运行.NET 4.7.2)上实现错误处理,以避免将来遇到错误,因为我们有几天前。

错误是Web.Config文件中的此代码尚未更新,但项目发布时项目附带的DLL已更新,因此版本之间不匹配。

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs"
        type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
        type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
    </compilers>
  </system.codedom>

两个Version=2.0.1.0行中的compiler都设置为Version=1.0.8.0,并且已发布的DLL版本是2.0.1.0。这给出了一个看起来像这样的错误:

Image that shows the exception

现在,我想在代码中处理此异常,并将其记录到我们的日志记录堆栈中。我四处搜索,发现在web.api项目中捕获异常的几种不同方法,但是似乎没有一种有效。我尝试过的是:

global.asax.cs文件中:

        void Application_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError();

            if (ex != null)
                Logger.WriteToFile(ex.Message, ex);
        }

也在global.asax.cs文件中:

        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);

            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = (e.ExceptionObject as Exception);

            if (ex != null) 
                Logger.WriteToFile(ex.Message, ex);
        }

在自动添加到Web.API的WebApiConfig.Register函数中(例如,处理路由设置):

        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Filters.Add(new GlobalExceptionFilterAttribute()); // <-- this line

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

    public class GlobalExceptionFilterAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            var exceptionType = context.Exception.GetType().ToString();
            var exception = context.Exception.InnerException ?? context.Exception;

            try
            {
                if (exception != null)
                    Logger.WriteToFile(exception.Message, exception);
            }
            finally
            {
                base.OnException(context);
            }
        }
    }

在web.config文件中,我添加了一个模块,该模块应该(理论上)处理IIS级别的错误(取自Catch IIS level error to handle in ASP.NET):

  <system.webServer>
    <modules>
      <add type="ErrorHttpModule" name="ErrorHttpModule"/>
    </modules>
  </system.webServer>
public class ErrorHttpModule : IHttpModule
{
    private HttpApplication _context;

    public ErrorHttpModule() { }

    public void Init(HttpApplication context)
    {
        _context = context;
        _context.Error += new EventHandler(ErrorHandler);
    }

    private void ErrorHandler(object sender, EventArgs e)
    {
        Exception ex = _context.Server.GetLastError();

        if (ex != null)
            Logger.WriteToFile(ex.Message, ex);
    }

    public void Dispose()
    {
    }
}

这些似乎都没有发现错误并记录下来。如何捕获此错误?

除了主项目外,我还在一个完全空白的Web.API项目中重现了此错误。可以在https://github.com/Loyalar/IISExceptionCapture上找到空白的Web.API项目。

2 个答案:

答案 0 :(得分:0)

故障排除:

  1. 启用了stdoutLogEnabled并检查了IIS日志。

  2. 您还可以检查窗口日志事件。

引荐-https://weblog.west-wind.com/posts/2020/Jan/14/ASPNET-Core-IIS-InProcess-Hosting-Issues-in-NET-Core-31

答案 1 :(得分:0)

您可以在应用程序的开头使用以下代码。在Program.cs,Startup.cs或您的Global.asax文件中。

AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
    Debug.WriteLine(eventArgs.Exception.ToString());
};

请参阅下面的链接以获取更多详细信息:

https://stackify.com/csharp-catch-all-exceptions/

catch all unhandled exceptions in ASP.NET Web Api