2009-09-23 84 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調用的安全措施。