C# global.asax中的应用程序_错误未捕获WebAPI中的错误

C# global.asax中的应用程序_错误未捕获WebAPI中的错误,c#,asp.net,.net,asp.net-web-api,error-reporting,C#,Asp.net,.net,Asp.net Web Api,Error Reporting,对于我正在从事的一个项目,我们正在实施的一件事情是,我们在我的一些团队中为旧的ASP.NET和MVC项目编写了代码-一个应用程序错误异常捕获器,它向开发团队发送一封电子邮件,其中包含异常体验和最相关的详细信息 下面是它的外观: Global.asax: protected void Application_Error(object sender, EventArgs e) { Exception ex = Server.GetLastError(); string path =

对于我正在从事的一个项目,我们正在实施的一件事情是,我们在我的一些团队中为旧的ASP.NET和MVC项目编写了代码-一个
应用程序错误
异常捕获器,它向开发团队发送一封电子邮件,其中包含异常体验和最相关的详细信息

下面是它的外观:

Global.asax:

protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    string path = "N/A";
    if (sender is HttpApplication)
        path = ((HttpApplication) sender).Request.Url.PathAndQuery;

    string args = string.Format("<b>Path:</b> {0}", path);

    // Custom code that generates an HTML-formatted exception dump
    string message = Email.GenerateExceptionMessage(ex, args);

    // Custom code that sends an email to the dev team.
    Email.SendUnexpectedErrorMessage("Some App", message);
}
前端JavaScript会立即拦截HTTP 500请求,但无法访问上面提到的global.asax.cs代码(我在方法的第一个执行行设置了断点)


问题:如何让“旧”的
应用程序错误处理程序发送错误电子邮件,以便我们团队的开发人员能够更轻松地调试我们的应用程序?

将您的错误处理逻辑从
应用程序错误
提取到自己的函数中。创建一个


来自Web API的错误不会触发应用程序错误事件。但是我们可以创建一个异常过滤器并注册它来处理错误。另请参见。

将您的错误处理逻辑从
应用程序\u error
提取到它自己的函数中。创建一个


来自Web API的错误不会触发应用程序错误事件。但是我们可以创建一个异常过滤器并注册它来处理错误。另请参见。

在我的情况下,我不喜欢使用Web.config。然后我在Global.asax文件中创建了上面的代码:

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

        //Not Found (When user digit unexisting url)
        if(ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)
        {
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "NotFound");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        }
        else //Unhandled Errors from aplication
        {
            ErrorLogService.LogError(ex);
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Index");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        }
    }
这是我的ErrorController.cs

public class ErrorController : Controller
{
    // GET: Error
    public ViewResult Index()
    {
        Response.StatusCode = 500;
        Exception ex = Server.GetLastError();
        return View("~/Views/Shared/SAAS/Error.cshtml", ex);
    }

    public ViewResult NotFound()
    {
        Response.StatusCode = 404;
        return View("~/Views/Shared/SAAS/NotFound.cshtml");
    }
}
这是我从@mason class复制的ErrorLogService.cs

//common service to be used for logging errors
public static class ErrorLogService
{
    public static void LogError(Exception ex)
    {
        //Do what you want here, save log in database, send email to police station
    }
}

在我的情况下,我不喜欢使用Web.config。然后我在Global.asax文件中创建了上面的代码:

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

        //Not Found (When user digit unexisting url)
        if(ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)
        {
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "NotFound");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        }
        else //Unhandled Errors from aplication
        {
            ErrorLogService.LogError(ex);
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Index");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        }
    }
这是我的ErrorController.cs

public class ErrorController : Controller
{
    // GET: Error
    public ViewResult Index()
    {
        Response.StatusCode = 500;
        Exception ex = Server.GetLastError();
        return View("~/Views/Shared/SAAS/Error.cshtml", ex);
    }

    public ViewResult NotFound()
    {
        Response.StatusCode = 404;
        return View("~/Views/Shared/SAAS/NotFound.cshtml");
    }
}
这是我从@mason class复制的ErrorLogService.cs

//common service to be used for logging errors
public static class ErrorLogService
{
    public static void LogError(Exception ex)
    {
        //Do what you want here, save log in database, send email to police station
    }
}


您可以将错误处理逻辑抽象到一个单独的方法中,该方法调用
Application\u error
,将Web API方法体包装在try/catch中,然后手动将错误逻辑从Web API错误传递给抽象的方法。我确信这不是最干净的方式,但它应该是直接实现和“正常工作”的。我同意这是一个很好的“让它工作起来”的建议。我问这个问题的原因是,根据我的技术主管的指导,在每个API方法中都有一个
try/catch
,这实际上是我想要逃避的。但是,如果所有其他方法都失败了,我们的团队可以将此作为后备方案。这将是一个非常令人讨厌的模式。我编辑了我最后的评论。看看我提供的链接,看看异常过滤器。这看起来是避免在所有WebAPI方法体中使用try/catch的一个不错的方法。这最终对我来说是可行的。您是否介意回答一下您的评论,即使用异常过滤器是一种更好的方法?您可以将错误处理逻辑抽象到一个单独的方法中,
Application\u error
调用,将Web API方法体包装在try/catch中,然后手动将错误逻辑从Web API错误传递给抽象方法。我确信这不是最干净的方式,但它应该是直接实现和“正常工作”的。我同意这是一个很好的“让它工作起来”的建议。我问这个问题的原因是,根据我的技术主管的指导,在每个API方法中都有一个
try/catch
,这实际上是我想要逃避的。但是,如果所有其他方法都失败了,我们的团队可以将此作为后备方案。这将是一个非常令人讨厌的模式。我编辑了我最后的评论。看看我提供的链接,看看异常过滤器。这看起来是避免在所有WebAPI方法体中使用try/catch的一个不错的方法。这最终对我来说是可行的。您是否介意回答您的评论,即使用异常过滤器是一种更好的方法?为什么?我不明白。这是最好的做法?@LeandroDeMelloFagundes当Web API出现异常时,不会触发应用程序错误事件。您可能已经出现登录应用程序错误,无法处理ASP.NET异常。因此,将该逻辑放在公共服务中,可以从应用程序错误或应用于Web API操作方法的异常过滤器中使用,遵循DRY原则。没有重复的逻辑。感谢@mason,阅读asp.net网站上关于您答案的链接也有助于理解发生了什么。伟大的aswerLOL打电话给消防部门:-):-)你应该把这行放在哪里:GlobalConfiguration.Configuration.Filters.Add(新的LogExceptionFilterAttribute());是在global.asax Application_Start()还是Application_Error()中?为什么?我不明白。这是最好的做法?@LeandroDeMelloFagundes当Web API出现异常时,不会触发应用程序错误事件。您可能已经出现登录应用程序错误,无法处理ASP.NET异常。因此,将该逻辑放在公共服务中,可以从应用程序错误或应用于Web API操作方法的异常过滤器中使用,遵循DRY原则。没有重复的逻辑。感谢@mason,阅读asp.net网站上关于您答案的链接也有助于理解发生了什么。伟大的aswerLOL打电话给消防部门:-):-)你应该把这行放在哪里:GlobalConfiguration.Configuration.Filters.Add(新的LogExceptionFilterAttribute());它是在global.asax Application_Start()还是Application_Error()中?这不会回答OP的问题,他的代码也不会引用Web.config。这不会回答OP的问题,他的代码也不会引用Web.config。