2013-02-28 72 views
2

我處理我的控制器錯誤,我有[CustomErrorHandleAttribute]這是我寫的時候沒有在我的行動異常做什麼處理。即使在我的代碼中沒有錯誤,它將重定向到errorrorhandle並拋出錯誤。我無法找到錯誤的原因。自定義錯誤MVC中不工作

這裏是我的代碼:

namespace ExceptionHandlingInMVC.Controllers 
    { 
    [CustomHandleError] 
    public class HomeController : Controller 
    { 
     // 
     // GET: /Home/ 

     public object Index() 
     { 
      try 
      { 
       ViewData["Title"] = "Home Page"; 
       ViewData["Message"] = "Current time is:" + DateTime.Now.ToLongTimeString(); 
       var x = 10; 
       var y = 10; 
       var result = x/y; 
       ViewData["Result"] = result; 
       return View(); 
      } 
      catch (Exception e) 
      { 

       throw e; 
      } 

     } 

     [CustomHandleError] 
     public object About() 
     { 
      ViewData["Title"] = "About Page"; 
      return View(); 
     } 
    } 

    public class ErrorPresentation 
    { 
     public String ErrorMessage { get; set; } 
     public Exception TheException { get; set; } 
     public Boolean ShowMessage { get; set; } 
     public Boolean ShowLink { get; set; } 


    } 

    } 

CustomHandleErrorAttribute,我已經寫了:

namespace ExceptionHandlingInMVC 
    { 

    /// <summary> 
    /// This attribute (AOP) filter is used to override the Error handling and make sure that all erros are recorded in the event logs, so that they can in turn be picked up by 
    /// our SIEM tool so that we a) stop customers seing a bad error message and b) we are capturing all the events that happen and c) improives security for 
    /// by preventing a hacker from seing s=details of how our application is put together 
    /// </summary> 
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
    public sealed class CustomHandleErrorAttribute : ActionFilterAttribute 
    { 
     /// <summary> 
     /// This event is called when the action is called i.e. an error has just occured 
     /// </summary> 
     /// <param name="filterContext"></param> 
     public override void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      try 
      { 
       // Bail if we can't do anything; app will crash. 
       if (filterContext == null) 
        return; 

       // since we're handling this, log to ELMAH(Error logging modules and handler) 
       var ex = filterContext.Exception ?? new Exception("No further information exists."); 
       WriteToEventLog(ex); 

       filterContext.ExceptionHandled = true; 
       var data = new ErrorPresentation 
       { 
        ErrorMessage = HttpUtility.HtmlEncode(ex.Message), 
        TheException = ex, 
        ShowMessage = filterContext.Exception != null, 
        ShowLink = false 
       }; 

       filterContext.Result = new ViewResult 
       { 
        ViewName = "~/Views/Home/ErrorPage.aspx" 
       }; 
      } 
      catch (Exception exception) 
      { 

       throw; 
      } 

     } 

     /// <summary> 
     /// This method writes the exception to the event log we have specified in the web.config or the app.config 
     /// </summary> 
     /// <param name="exception"></param> 
     public void WriteToEventLog(Exception exception) 
     { 
      // pick up which machine we are on, this will already be set for all websites 
      var machineName = ConfigurationManager.AppSettings["MachineName"]; 

      // PIck up the eventlog we are going to write to 
      var eventLogName = ConfigurationManager.AppSettings["EventLogName"]; 

      EventLog.WriteEntry("abc", exception.Message, EventLogEntryType.Error); 

     } 
    } 
} 
+0

你並不真的需要創建自己的屬性,只需覆蓋'Application_Error'在Global.asax的,把你的自定義日誌記錄代碼在那裏。 – mattytommo 2013-02-28 12:29:36

+1

但是爲了幫助你,我會打賭,屬性不甚至被解僱的錯誤,因爲你已經overrided'OnActionExecuted',這將不會在錯誤點發生。 – mattytommo 2013-02-28 12:30:18

+0

@mattytommo我現在不重寫我的代碼工作時,有沒有錯誤,我的錯誤處理時出現錯誤 – 62071072SP 2013-02-28 12:39:27

回答

2

你確實應該進行錯誤處理在global.asax中覆蓋Application_Error。這樣,您可以確保您的代碼只會在發生錯誤時執行。使用OnActionExecuted意味着你的代碼將執行不管或無論是否引發錯誤

這裏的功能:

void Application_Error(object sender, EventArgs e) 
{ 
    //do your stuff here 
} 
2

試試這個:

public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     try 
     { 
      // Bail if we can't do anything; app will crash. 
      if (filterContext == null) 
       return; 

      // since we're handling this, log to ELMAH(Error logging modules and handler) 
      if (filterContext.Exception == null || filterContext.ExceptionHandled) 
      { 
       var ex = filterContext.Exception ?? new Exception("No further information exists."); 
       this.WriteToEventLog(ex); 
       return; 
      }; 

      filterContext.ExceptionHandled = true; 
      var data = new ErrorPresentation 
      { 
       ErrorMessage = HttpUtility.HtmlEncode(ex.Message), 
       TheException = ex, 
       ShowMessage = filterContext.Exception != null, 
       ShowLink = false 
      }; 

      filterContext.Result = new ViewResult 
      { 
       ViewName = "~/Views/Home/ErrorPage.aspx" 
      }; 
     } 
     catch (Exception exception) 
     { 

      throw; 
     } 

    } 

如果沒有exeption你需要返回,因爲這個屬性每次都會觸發,而不僅僅是當你有錯誤時。

更新: 我建議你在Global.asax中下面寫代碼:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new CustomErrorHandle()); 
    } 

這個attibute火到所有動作。所以你不需要爲任何動作寫屬性。

+0

謝謝你的工作 – 62071072SP 2013-02-28 13:02:33

0

時,只有錯誤事件應該被解僱,我寫事件日誌:

在我的Global.asax添加以下代碼:

/// <summary> 
    /// Managing errors from a single location 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    void Application_Error(object sender, EventArgs e) 
    { 
     // 1. Get the last error raised 
     var error = Server.GetLastError(); 

     //2. Get the error code to respond with 
     var code = (error is HttpException) ? (error as HttpException).GetHttpCode() : 500; 

     //3.. Log the error (I am ignoring 404 error) 
     if (code != 404) 
     { 
      // Write error details to eventlog 
      WriteToEventLog(error); 
     } 

     //4. Clear the response stream 
     Response.Clear(); 

     //5. Clear the server error 
     Server.ClearError(); 

     //6. Render the Error handling controller without a redirect 
     string path = Request.Path; 
     Context.RewritePath(string.Format("~/Home/Error",code),false); 
     IHttpHandler httpHandler = new MvcHttpHandler(); 
     httpHandler.ProcessRequest(Context); 
     Context.RewritePath(path,false); 
    } 

    /// <summary> 
    /// This method writes the exception to the event log we have specified in the web.config or the app.config 
    /// </summary> 
    /// <param name="exception"></param> 
    public void WriteToEventLog(Exception exception) 
    { 
     EventLog.WriteEntry("abc", exception.Message, EventLogEntryType.Error); 
    }