代码之家  ›  专栏  ›  技术社区  ›  Kevin Pang

在ASP.NET MVC中记录错误

  •  103
  • Kevin Pang  · 技术社区  · 16 年前

    我目前正在我的ASP.NET MVC应用程序中使用log4net来记录异常。我这样做的方法是让我的所有控制器从一个basecontroller类继承。在BaseController的OnActionExecuting事件中,我记录可能发生的任何异常:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // Log any exceptions
        ILog log = LogManager.GetLogger(filterContext.Controller.GetType());
    
        if (filterContext.Exception != null)
        {
            log.Error("Unhandled exception: " + filterContext.Exception.Message +
                ". Stack trace: " + filterContext.Exception.StackTrace, 
                filterContext.Exception);
        }
    }
    

    如果在控制器操作过程中发生未处理的异常,这将非常有效。

    对于404错误,我在web.config中设置了一个自定义错误,如下所示:

    <customErrors mode="On">
        <error statusCode="404" redirect="~/page-not-found"/>
    </customErrors>
    

    在处理“找不到页面”URL的控制器操作中,我记录请求的原始URL:

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult PageNotFound()
    {
        log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"]));
    
        return View();
    }
    

    这也是可行的。

    我遇到的问题是如何记录.aspx页面上的错误。假设我在其中一个页面上有一个编译错误,或者一些内联代码将引发异常:

    <% ThisIsNotAValidFunction(); %>
    <% throw new Exception("help!"); %>
    

    handleError属性似乎正确地将其重新路由到共享文件夹中的my error.aspx页,但它绝对不会被basecontroller的onActionExecuted方法捕获。我想我可以把日志代码放到error.aspx页面上,但是我不确定如何在那个级别上检索错误信息。

    6 回复  |  直到 7 年前
        1
  •  98
  •   Community CDub    8 年前

    我会考虑通过插入来简化您的Web应用程序 Elmah .

    将elmah程序集添加到项目中,然后配置web.config。然后它将记录在控制器或页面级别创建的异常。它可以配置为登录到不同的地方(如SQL Server、电子邮件等)。它还提供了一个Web前端,以便您可以浏览异常日志。

    这是我添加到我创建的任何ASP.NET MVC应用程序中的第一件事。

    我仍然使用log4net,但我倾向于使用它来记录调试/信息,并将所有异常留给elmah。

    您还可以在问题中找到更多信息 How do you log errors (Exceptions) in your ASP.NET apps? .

        2
  •  36
  •   Chuck Conway    16 年前

    您可以在global.asax中钩住onerror事件。

    像这样:

    /// <summary>
    /// Handles the Error event of the Application control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    protected void Application_Error(object sender, EventArgs e)
    {
        if (Server != null)
        {
            Exception ex = Server.GetLastError();
    
            if (Response.StatusCode != 404 )
            {
                Logging.Error("Caught in Global.asax", ex);
            }
    
        }
    
    
    }
    
        3
  •  20
  •   Mark    13 年前

    MVC3
    创建继承自handleerorrinfoattribute的属性,包括您选择的日志记录。

    public class ErrorLoggerAttribute : HandleErrorAttribute 
    {
        public override void OnException(ExceptionContext filterContext)
        {
            LogError(filterContext);
            base.OnException(filterContext);
        }
    
        public void LogError(ExceptionContext filterContext)
        {
           // You could use any logging approach here
    
            StringBuilder builder = new StringBuilder();
            builder
                .AppendLine("----------")
                .AppendLine(DateTime.Now.ToString())
                .AppendFormat("Source:\t{0}", filterContext.Exception.Source)
                .AppendLine()
                .AppendFormat("Target:\t{0}", filterContext.Exception.TargetSite)
                .AppendLine()
                .AppendFormat("Type:\t{0}", filterContext.Exception.GetType().Name)
                .AppendLine()
                .AppendFormat("Message:\t{0}", filterContext.Exception.Message)
                .AppendLine()
                .AppendFormat("Stack:\t{0}", filterContext.Exception.StackTrace)
                .AppendLine();
    
            string filePath = filterContext.HttpContext.Server.MapPath("~/App_Data/Error.log");
    
            using(StreamWriter writer = File.AppendText(filePath))
            {
                writer.Write(builder.ToString());
                writer.Flush();
            }
        }
    

    将属性放入global.asax registerglobalfilters

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
           // filters.Add(new HandleErrorAttribute());
            filters.Add(new ErrorLoggerAttribute());
        }
    
        4
  •  1
  •   Kieron    16 年前

    你想过扩展handleError属性吗?此外,Scott有一篇关于控制器/操作的过滤器截取器的好博客文章。 here .

        5
  •  1
  •   Praveen Angyan    16 年前

    error.aspx视图的定义如下:

    namespace MvcApplication1.Views.Shared
    {
        public partial class Error : ViewPage<HandleErrorInfo>
        {
        }
    }
    

    handleerorrinfo有三个特性: 字符串actionname 字符串控制器名称 异常异常

    您应该能够访问handleerorrinfo,从而访问视图中的异常。

        6
  •  0
  •   Mike Chaliy    16 年前

    您可以尝试检查httpContext.error,但我对此不确定。