如何讓 ELMAH 與 ASP.NET MVC [HandleError] 屬性一起使用?
我正在嘗試使用 ELMAH 在我的 ASP.NET MVC 應用程序中記錄錯誤,但是當我在控制器上使用 [HandleError] 屬性時,ELMAH 在發生錯誤時不會記錄任何錯誤。
正如我猜測的那樣,因為 ELMAH 只記錄未處理的錯誤,而 [HandleError] 屬性正在處理錯誤,因此無需記錄它。
我如何修改或如何修改屬性,以便 ELMAH 可以知道存在錯誤並記錄它..
**編輯:**讓我確保每個人都理解,我知道我可以修改屬性,這不是我要問的問題…使用 handleerror 屬性時,ELMAH 被繞過,這意味著它不會看到有錯誤,因為它已被處理已經由屬性…我要問的是有沒有辦法讓 ELMAH 看到錯誤並記錄它,即使屬性處理了它…我四處搜尋,沒有看到任何方法可以呼叫來強制它記錄錯誤….
您可以子類化
HandleErrorAttribute並覆蓋其OnException成員(無需複制),以便它使用 ELMAH 記錄異常,並且僅當基本實現處理它時。您需要的最少程式碼如下:using System.Web.Mvc; using Elmah; public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute { public override void OnException(ExceptionContext context) { base.OnException(context); if (!context.ExceptionHandled) return; var httpContext = context.HttpContext.ApplicationInstance.Context; var signal = ErrorSignal.FromContext(httpContext); signal.Raise(context.Exception, httpContext); } }首先呼叫基本實現,使其有機會將異常標記為正在處理。只有這樣才會發出異常信號。
HttpContext上面的程式碼很簡單,如果在測試等可能不可用的環境中使用,可能會導致問題。因此,您將需要更具防禦性的程式碼(以稍長一些為代價):using System.Web; using System.Web.Mvc; using Elmah; public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute { public override void OnException(ExceptionContext context) { base.OnException(context); if (!context.ExceptionHandled // if unhandled, will be logged anyhow || TryRaiseErrorSignal(context) // prefer signaling, if possible || IsFiltered(context)) // filtered? return; LogException(context); } private static bool TryRaiseErrorSignal(ExceptionContext context) { var httpContext = GetHttpContextImpl(context.HttpContext); if (httpContext == null) return false; var signal = ErrorSignal.FromContext(httpContext); if (signal == null) return false; signal.Raise(context.Exception, httpContext); return true; } private static bool IsFiltered(ExceptionContext context) { var config = context.HttpContext.GetSection("elmah/errorFilter") as ErrorFilterConfiguration; if (config == null) return false; var testContext = new ErrorFilterModule.AssertionHelperContext( context.Exception, GetHttpContextImpl(context.HttpContext)); return config.Assertion.Test(testContext); } private static void LogException(ExceptionContext context) { var httpContext = GetHttpContextImpl(context.HttpContext); var error = new Error(context.Exception, httpContext); ErrorLog.GetDefault(httpContext).Log(error); } private static HttpContext GetHttpContextImpl(HttpContextBase context) { return context.ApplicationInstance.Context; } }第二個版本將首先嘗試使用來自 ELMAH 的錯誤信號,這涉及到完全配置的管道,如日誌記錄、郵件、過濾和你有什麼。如果做不到這一點,它會嘗試查看是否應該過濾錯誤。如果不是,則簡單地記錄錯誤。此實現不處理郵件通知。如果可以發出異常信號,則如果配置為發送郵件,則會發送郵件。
您可能還必須注意,如果多個
HandleErrorAttribute實例生效,則不會發生重複日誌記錄,但上述兩個範例應該可以幫助您入門。