2009-06-23 151 views
22

我要尋找一個簡單的解決方案做的異常記錄,錯誤在我的ASP.Net MVC 1.0應用程序處理合並相結合。ASP.Net MVC異常日誌記錄與錯誤處理

我讀過很多文章,這裏包括在計算器上發表的問題,這都提供了不同的情況不同的解決方案。我仍然無法想出一個適合我需求的解決方案。

這裏是我的要求:

  1. 爲了能夠在我的控制器使用下,[HandleError]屬性(或東西等效),以處理可能從任何動作或視圖被拋出的所有異常。這應該處理所有在任何操作中沒有專門處理的異常(如第2點所述)。我希望能夠指定哪些用戶必須重定向到錯誤情況下的所有操作。

  2. 我希望能夠在特定操作的頂部指定[HandleError]屬性(或類似的東西)來捕捉特定的異常並將用戶重定向到適合該異常的視圖。所有其他異常仍然必須由控制器上的[HandleError]屬性處理。

  3. 在上述兩種情況下,我想用log4net的(或任何其它的日誌庫)中記錄的異常。

我該如何去實現上述目標?我讀過有關讓我所有的控制器從基本控制器將覆蓋onException的方法繼承,其中我做我的記錄。但是,這會混淆將用戶重定向到適當的視圖,或使其變得混亂。

我讀過關於寫它實現個IExceptionFilter來處理這個我自己的篩選器操作,但這將與[的HandleError]屬性衝突。

到目前爲止,我的想法是,最好的解決辦法是寫我自己的屬性,從HandleErrorAttribute繼承。這樣我就可以獲得[HandleError]的所有功能,並且可以添加我自己的log4net日誌記錄。解決方案如下:

public class HandleErrorsAttribute: HandleErrorAttribute { 

     private log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

     public override void OnException(ExceptionContext filterContext) 
     { 
      if (filterContext.Exception != null) 
      { 
      log.Error("Error in Controller", filterContext.Exception); 
      } 

      base.OnException(filterContext); 
     } 
    } 

上述代碼是否適合我的要求?如果不是,哪種解決方案能滿足我的要求?

回答

24

我還是有點糊塗了所有不同的解決方案在那裏,以及如何屬性可以互相干擾,但我用這個解決方案去:

public class LogErrorsAttribute: FilterAttribute, IExceptionFilter 
{ 
    #region IExceptionFilter Members 

    void IExceptionFilter.OnException(ExceptionContext filterContext) 
    { 
     if (filterContext != null && filterContext.Exception != null) 
     { 
      string controller = filterContext.RouteData.Values["controller"].ToString(); 
      string action = filterContext.RouteData.Values["action"].ToString(); 
      string loggerName = string.Format("{0}Controller.{1}", controller, action); 

      log4net.LogManager.GetLogger(loggerName).Error(string.Empty, filterContext.Exception); 
     } 

    } 

    #endregion 
} 

我還是用下,[HandleError]屬性正如原來的問題所解釋的那樣,我只是用一個[LogErrors]屬性來修飾每個控制器。

這對我有用,因爲它將錯誤記錄保存在一個地方,並且不會導致重複記錄多次異常(如果我擴展[HandleError]並在多個位置使用該屬性,就會發生這種情況)。

我不認爲這將有可能同時異常日誌記錄和錯誤處理成一個atrribute或類結合,沒有它變得非常繁瑣和複雜,或影響使用[的HandleError]

,但這適用於我,因爲我只用一次[LogErrors]屬性裝飾每個控制器,並用[HandleError]裝飾控制器和動作,而不是互相干擾。

更新:

這裏是如何使用它的一個例子:

[LogErrors(Order = 0)] 
[HandleError(Order = 99)] 
public class ContactController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(Views.Index); 
    } 

    public ActionResult Directions() 
    { 
     return View(Views.Directions); 
    } 


    public ActionResult ContactForm() 
    { 
     FormContactMessage formContactMessage = new FormContactMessage(); 

     return View(Views.ContactForm,formContactMessage); 
    } 

    [HandleError(ExceptionType = typeof(SmtpException), View = "MessageFailed", Order = 1)] 
    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult ContactForm(FormContactMessage formContactMessage) 
    { 
     if (ModelState.IsValid) 
     { 
      if (formContactMessage.IsValid) 
      { 
       SmtpClient client = new SmtpClient(); 

       MailAddress recipientAddress = new MailAddress(Properties.Settings.Default.ContactFormRecipientEmailAddress); 
       MailAddress senderAddress = new MailAddress(Properties.Settings.Default.ContactFormSenderEmailAddress); 
       MailMessage mailMessage = formContactMessage.ToMailMessage(recipientAddress, senderAddress); 

       client.Send(mailMessage); 

       return View("MessageSent"); 
      } 
      else 
      { 
       ModelState.AddRuleViolations(formContactMessage.GetRuleViolations()); 
      } 
     } 
     return View(Views.ContactForm, formContactMessage); 
    } 

    private static class Views 
    { 
     public static string Index { get { return "Index"; } } 
     public static string Directions { get { return "Directions"; } } 
     public static string ContactForm { get { return "ContactForm"; } } 

    } 
} 

在上面的代碼,在ContactForm行動超載SmtpExceptions在一個非常特殊的方式處理 - 用戶與查看失敗的發送消息相關的ViewPage,在這種情況下,它被稱爲「MessageFailed」。所有其他異常都由[HandleError]的默認行爲處理。另請注意,首先發生錯誤記錄,然後處理錯誤。這是由以下指示:

[LogErrors(Order = 0)] 
[HandleError(Order = 99)] 

更新:

,有一種替代解決這個,有一個非常好的explanantion。我建議通讀它以更好地理解所涉及的問題。

ASP.NET MVC HandleError Attribute, Custom Error Pages and Logging Exceptions (感謝下面的Scott Shepherd,誰在下面的答案中提供了鏈接)。

+0

不錯,非常感謝,我會用這個。 – Kezzer 2009-09-18 10:48:29