onException的在基本控制器沒有捕捉所有的錯誤 (特別是如果不是所有的控制器繼承它)。
HandleErrorAttribute將需要您逐個應用該屬性。或者使用全局過濾器應用它,但它對所有控制器都是一樣的。
關閉customErrors將只顯示錯誤,不處理它。而且您無法爲不同類型的錯誤提供不同的視圖。
我們通常做的是這樣的:
安裝ELMAH或類似的包裝,以保持所有錯誤的軌道,即使他們默默發生。
然後,在Global.asax中:
protected void Application_Error(object sender, EventArgs e)
{
//Retrieving the last server error
var exception = Server.GetLastError();
//Erases any buffered HTML output
Response.Clear();
var httpException = exception as HttpException;
var routeData = new RouteData();
routeData.Values.Add("controller", "Error"); //Adding a reference to the error controller
if (httpException == null)
{
routeData.Values.Add("action", "ServerError"); //Non HTTP related error handling
}
else //It's an Http Exception, Let's handle it.
{
switch (httpException.GetHttpCode())
{
case 401:
case 403:
//Forbidden page.
routeData.Values.Add("action", "Forbidden");
break;
case 404:
//Page not found.
routeData.Values.Add("action", "NotFound");
break;
case 500:
routeData.Values.Add("action", "ServerError");
break;
default:
routeData.Values.Add("action", "Index");
break;
}
}
//Pass exception details to the target error View.
routeData.Values.Add("message", exception);
//Clear the error on server.
Server.ClearError();
//Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
我們覺得這是給我們在處理大多數控制和如何展現我們的遊客的選項。所顯示的每個操作(servererror,notfound和forbidden)都有不同的屏幕,並且取決於服務器是在調試還是釋放時運行,那麼我們將顯示堆棧跟蹤信息與否(但我們始終使用ELMAH捕獲它,以便始終可以看到它有)
Elmah很棒,但有一些缺陷 - 它不會捕獲WCF服務錯誤,以及StackOverflowException和OutOfMemoryException。 –
@OndrejSvejdar - 無論如何StackOverflow和OutOfMemory幾乎都是不可恢復的,所以如果沒有發現它們就沒關係。 –
我的控制器都是從同一個類繼承的,我正在尋找一個全局解決方案。那麼爲什麼有'OnException'和'HandleErrorAttribute',如果我可以在'Application_Error'中做所有事情?有兩個重定向位置('customErrors'和'HandleErrorAttribute')有什麼意義? –