[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來自動幫你擷取相關列外訊息。
參考