2009-09-23 85 views
14

我想在我的MVC项目中使用Application_Error,但是我无法让它工作。我以下内容添加到我的Global.asax文件:(会话仅用于测试我也会使用数据库来记录错误,如果我得到这个工作。)如何在ASP.NET MVC中使用Application_Error?

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

然后我试图抛出从我的HomeController和我的Home/Index视图异常,但它只触发调试。

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

在我Webconfig文件我设置defaulterror页,但它并没有重定向到视图:

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

回答

14

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

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中设置默认错误页面。配置那么你不需要重定向

<customErrors defaultRedirect="Home/Error" /> 

但是,除非你已经添加了一个错误,以便您的家庭控制器不存在,那么添加下面给家庭控制器

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

然后(如果你是明智的),你会把错误处理代码放在Error()方法中,因为这是所有未处理错误最终会发生的地方。

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

终于记住,如果您连接到本地主机,默认情况下您不会看到自定义错误!所以你需要改变这种行为

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

我有你的解决方案的问题。 CustomErrors直接重定向到Home/Errors视图,而不触发Controller。我不知道这是可能的,但是当我在Error Action方法中放置一个调试点时,调试从不会调用。错误视图只显示在屏幕上,但url仍然与触发错误的URL相同。例如,如果我在/ Home/Job触发错误,我会得到错误视图,但URL仍然是/家/作业 – Poku 2009-09-23 15:52:32

+18

嘿@blowdart:消息提供一个新用户无法评论:这个答案是平坦的错误。问题是如果使用web.config重定向到默认控制器操作,则从控制器类调用Server.GetLastError()不起作用。 ASP向错误控制器发起一个新的HTTP请求,该错误控制器将清除服务器变量,从而丢失异常信息。 – 2011-06-08 20:19:05

+3

不好的答案.....这里是一个很好的文章,为什么你应该同时使用http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc – 2013-11-08 14:12:10

1
  • 你有会话成立摆在首位?如果错误是由IHttpHandler(未标记为IRequiresSessionState)触发的,则访问Session将失败。
  • 你在做什么Session["Test"]?你确定你的代码实际上不工作吗?你可以尝试一个File.Open,并简单地输出一些文本(比如当前时间)到C:\my-log.txt,这比使用Session更有可能成功。
  • GetBaseException在这种情况下(通常不用于记录)是无用的,据我所知。
  • Message是类型string - 调用.ToString()是没有必要的。一般来说,我强烈建议避免ToString()尽可能 - 如果你使用它,因为你不确定对象的类型,那应该是一个红旗;在类型系统周围做末端运行可以隐藏细微的错误(例如,DBNull.Value.ToString() == "")。对于图形用户界面,内置类型提供了对文化敏感的避免可移植性问题的.ToString(IFormatProvider)过载。由于object也不存在这种过载,所以它也是避免非常弱类型.ToString调用的安全措施。