【问题标题】:How do i use Application_Error in ASP.NET MVC?如何在 ASP.NET MVC 中使用 Application_Error?
【发布时间】:2010-11-30 16:11:56
【问题描述】:

我想在我的 MVC 项目中使用 Application_Error,但我无法让它工作。我将以下内容添加到我的 Global.asax 文件中:

    protected void Application_Error(object sender, EventArgs e)
    {
        Exception objErr = Server.GetLastError().GetBaseException();
        Session["Test"] = "Message:" + objErr.Message.ToString();
    }

(会话仅用于测试。如果我让它工作,我将使用数据库记录错误。) 然后我尝试从我的 HomeController 和我的 Home/Index 视图中抛出一个异常,但它只会触发 Debug。

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        throw (new Exception());
        return View();
    }

在我的 Webconfig 文件中,我设置了一个默认错误页面,但它不会重定向到视图:

    <customErrors defaultRedirect="Home/Error">
        <error statusCode="403" redirect="NoAccess.htm" />
        <error statusCode="404" redirect="FileNotFound.htm" />
    </customErrors>

【问题讨论】:

    标签: asp.net asp.net-mvc error-handling


    【解决方案1】:
    • 您是否首先设置了会话?如果错误是由未标记为IRequiresSessionStateIHttpHandler 触发的,则访问Session 将失败。
    • 你在用Session["Test"]做什么?您确定您的代码实际上不起作用吗?您可以尝试使用 File.Open 并简单地将一些文本(例如,当前时间)输出到 C:\my-log.txt,这比使用 Session 更容易成功。
    • 据我所知,GetBaseException 在这种情况下(通常也不适用于日志记录)没有用处。
    • Message 属于 string 类型 - 不需要调用 .ToString()。一般来说,我强烈建议尽可能避免 ToString() - 如果您因为不确定对象的类型而使用它,那应该是一个危险信号;围绕类型系统进行最终运行可以隐藏细微的错误(例如,DBNull.Value.ToString() == "")。对于 GUI,内置类型提供了.ToString(IFormatProvider) 重载,它对文化敏感并避免了可移植性问题。由于object 上也不存在这种重载,因此它也是一种避免非常弱类型的.ToString 调用的保障措施。

    【讨论】:

      【解决方案2】:

      所以首先要记住,全局错误处理应该是最后的手段,控制器类对错误有特定的错误方法;

      protected virtual bool OnError(string actionName, 
          System.Reflection.MethodInfo methodInfo, Exception exception)
      

      在此您可以重定向到标准共享错误视图;

      protected override bool OnError(string actionName, 
          System.Reflection.MethodInfo methodInfo, Exception exception)
      {
         RenderView("Error", exception);
         return false;
      }
      

      你在全局应用程序错误中遇到的问题是它没有视图或控制器的概念,所以如果你想在那里重定向,那么你必须使用一个已知的 URL

      protected void Application_Error(object sender, EventArgs e)
      {
          Exception exception = Server.GetLastError();
          System.Diagnostics.Debug.WriteLine(exception);
          Response.Redirect("/Home/Error");
      }
      

      但是你不需要这样做。如果您在 web.config 中设置了默认错误页面,则不需要该重定向

      <customErrors defaultRedirect="Home/Error" />
      

      但是,除非您在 Home 控制器中添加了不存在的错误视图,否则请在 Home 控制器中添加以下内容

      public ActionResult Error()
      {
          return View();
      }
      

      然后(如果您明智的话)您会将错误处理代码放在 Error() 方法中,因为所有未处理的错误都将在此处结束。

      public ActionResult Error()
      {
          Exception exception = Server.GetLastError();
          System.Diagnostics.Debug.WriteLine(exception);
          return View();
      }
      

      最后请记住,默认情况下,如果您连接到 localhost,您不会看到自定义错误!所以你需要改变这种行为

      <customErrors mode="On" defaultRedirect="/Home/Error" />
      

      【讨论】:

      • 我对您的解决方案有疑问。 CustomErrors 直接重定向到 Home/Errors 视图而不触发 Controller。我不知道这是可能的,但是当我在错误操作方法上放置一个调试点时,永远不会调用调试。错误视图只是显示在屏幕上,但 url 仍然与触发错误的 URL 相同。例如,如果我在 /Home/Job 触发错误,我将获得错误视图,但 URL 仍然是 /Home/Job
      • 嘿@blowdart:消息由无法评论的新用户提供:这个答案完全错误。问题是,如果您使用 web.config 重定向到默认控制器操作,则从控制器类调用 Server.GetLastError() 不起作用。 ASP 向错误控制器发起新的 HTTP 请求,这会清除服务器变量,丢失异常信息。
      • 错误答案.....这里有一篇很好的文章,介绍了为什么你应该同时使用prideparrot.com/blog/archive/2012/5/…
      • 有权限的人需要解决这个问题。这个答案是不正确的,而且非常具有误导性。
      • Bad answer..来自控制器类的Server.GetLastError() 不起作用!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 2012-09-06
      • 2011-02-12
      相关资源
      最近更新 更多