[C#][ASP.NET MVC]Error Handling
網頁開發中,對於Error Handling自己覺得還滿重要的,
在ASP.NET時自己都會在Global.aspx中的Application_Error事件來記錄整個網站應用程式相關未經處理的例外事件,
而在MVC當然也可以利用Application_Error事件(Global.asax)來達到同樣的需求,自己來實作並記錄一下。
1.Enabling Custom Error Handling
<customErrors mode="On" defaultRedirect="~/Error/General" >
<error statusCode="404" redirect="~/Error/StatusCode404"/>
<error statusCode="500" redirect="~/Error/StatusCode500"/>
</customErrors>
2.Write Application_Error in Global.asax.cs
using MVCcrud.Controllers;
protected void Application_Error( object sender, EventArgs e )
{
String Errormsg = String.Empty;
Exception unhandledException = Server.GetLastError();
Response.Clear();
HttpException httpException = unhandledException as HttpException;
Errormsg = "發生列外網頁:{0}錯誤訊息:{1}堆疊內容:{2}";
if( httpException != null )
{
RouteData routeData = new RouteData();
routeData.Values.Add( "controller", "Error" );
Errormsg = String.Format( Errormsg, Request.Path + Environment.NewLine,
unhandledException.GetBaseException().Message + Environment.NewLine, unhandledException.StackTrace + Environment.NewLine );
//寫入事件撿視器
EventLog.WriteEntry( "WebError", Errormsg, EventLogEntryType.Error );
//寫入文字檔
System.IO.File.AppendAllText( Server.MapPath( String.Format( "WebLog\\{0}.txt", DateTime.Now.ToString( "yyyy-MM-dd HH_mm_ss" ) ) ), Errormsg );
switch( httpException.GetHttpCode() )
{
case 404:
// page not found
routeData.Values.Add( "action", "StatusCode404" );
break;
case 500:
// server error
routeData.Values.Add( "action", "StatusCode500" );
break;
default:
routeData.Values.Add( "action", "General" );
break;
}
// Pass exception details to the target error View.
routeData.Values.Add( "Error", unhandledException );
// clear error on server
Server.ClearError();
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute( new RequestContext(
new HttpContextWrapper( Context ), routeData ) );
}
}
3.Create an ErrorController
[HandleError]
public class ErrorController : Controller
{
public ActionResult General( String error )
{
ViewData[ "Title" ] = "抱歉,處理你的請求發生錯誤";
ViewData[ "Description" ] = error;
return View( "Error" );
}
public ActionResult StatusCode404( String error )
{
ViewData[ "Title" ] = "抱歉, 處理你的請求發生404錯誤";
ViewData[ "Description" ] = error;
return View( "Error" );
}
public ActionResult StatusCode500( String error )
{
ViewData[ "Title" ] = "抱歉,處理你的請求發生500錯誤";
ViewData[ "Description" ] = error;
return View( "Error" );
}
}
4.Modify Error.aspx
<asp:Content ID="errorContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Title"]) %></h2>
<p><%= Html.Encode(ViewData["Description"])%></p>
<div>
<%= Html.ActionLink("返回首頁", "Index", "Home") %>.
</div>
</asp:Content>
測試:丟出Null Exception
public ActionResult Index()
{
ViewData[ "Message" ] = "Welcome to ASP.NET MVC!";
throw new ArgumentNullException();
return View();
}
結果:
View
事件檢視器
文字Log檔
輸入不存在的View
Error.aspx
事件檢視器
文字Log檔
當然如果不想這麼麻煩 ,可以使用log4net或elmah來自動幫你擷取相關列外訊息。
參考