[C#][ASP.NET MVC]Error Handling

  • 11773
  • 0
  • C#
  • 2010-03-09

[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

image

事件檢視器

image

文字Log檔

image

輸入不存在的View

Error.aspx

image 

事件檢視器

image

文字Log檔

image 

當然如果不想這麼麻煩 ,可以使用log4netelmah來自動幫你擷取相關列外訊息。

 

 

參考

HandleErrorAttribute

ASP.NET MVC Error Handler