Hiện tại đã có gói ELMAH.MVC trong NuGet bao gồm giải pháp cải tiến của Atif và cũng là bộ điều khiển xử lý giao diện elmah trong định tuyến MVC (không cần sử dụng axd đó nữa)
Vấn đề với giải pháp đó (và với tất cả các giải pháp ở đây ) là bằng cách này hay cách khác, trình xử lý lỗi elmah thực sự đang xử lý lỗi, bỏ qua những gì bạn có thể muốn thiết lập như một thẻ customError hoặc thông qua ErrorHandler hoặc trình xử lý lỗi của riêng bạn
Giải pháp tốt nhất IMHO là tạo một bộ lọc sẽ hoạt động ở cuối tất cả các bộ lọc khác và ghi nhật ký các sự kiện đã được xử lý. Mô-đun elmah nên chăm sóc để ghi lại các lỗi khác mà ứng dụng chưa xử lý. Điều này cũng sẽ cho phép bạn sử dụng máy theo dõi sức khỏe và tất cả các mô-đun khác có thể được thêm vào asp.net để xem xét các sự kiện lỗi
Tôi đã viết cái nhìn này với gương phản chiếu tại ErrorHandler bên trong elmah.mvc
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled) //The unhandled ones will be picked by the elmah module
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
//TODO: Add additional variables to context.HttpContext.Request.ServerVariables for both handled and unhandled exceptions
if ((context2 == null) || (!_RaiseErrorSignal(e, context2) && !_IsFiltered(e, context2)))
{
_LogException(e, context2);
}
}
}
private static bool _IsFiltered(System.Exception e, System.Web.HttpContext context)
{
if (_config == null)
{
_config = (context.GetSection("elmah/errorFilter") as ErrorFilterConfiguration) ?? new ErrorFilterConfiguration();
}
var context2 = new ErrorFilterModule.AssertionHelperContext((System.Exception)e, context);
return _config.Assertion.Test(context2);
}
private static void _LogException(System.Exception e, System.Web.HttpContext context)
{
ErrorLog.GetDefault((System.Web.HttpContext)context).Log(new Elmah.Error((System.Exception)e, (System.Web.HttpContext)context));
}
private static bool _RaiseErrorSignal(System.Exception e, System.Web.HttpContext context)
{
var signal = ErrorSignal.FromContext((System.Web.HttpContext)context);
if (signal == null)
{
return false;
}
signal.Raise((System.Exception)e, (System.Web.HttpContext)context);
return true;
}
}
Bây giờ, trong cấu hình bộ lọc của bạn, bạn muốn làm một cái gì đó như thế này:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//These filters should go at the end of the pipeline, add all error handlers before
filters.Add(new ElmahMVCErrorFilter());
}
Lưu ý rằng tôi đã để lại một bình luận ở đó để nhắc nhở mọi người rằng nếu họ muốn thêm bộ lọc toàn cầu thực sự sẽ xử lý ngoại lệ thì nên đi TRƯỚC bộ lọc cuối cùng này, nếu không, bạn sẽ gặp trường hợp ngoại lệ chưa được xử lý sẽ bị ElmahMVCErrorFilter bỏ qua nó chưa được xử lý và nó phải được ghi lại bởi mô-đun Elmah nhưng sau đó bộ lọc tiếp theo đánh dấu ngoại lệ là đã xử lý và mô-đun bỏ qua nó, dẫn đến ngoại lệ không bao giờ biến nó thành elmah.
Bây giờ, hãy đảm bảo các cài đặt ứng dụng cho elmah trong cấu hình web của bạn trông giống như thế này:
<add key="elmah.mvc.disableHandler" value="false" /> <!-- This handles elmah controller pages, if disabled elmah pages will not work -->
<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> <!-- This uses the default filter for elmah, set to disabled to use our own -->
<add key="elmah.mvc.requiresAuthentication" value="false" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.allowedRoles" value="*" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.route" value="errortracking" /> <!-- Base route for elmah pages -->
Điều quan trọng ở đây là "elmah.mvc.disableHandleErrorFilter", nếu điều này là sai, nó sẽ sử dụng trình xử lý bên trong elmah.mvc thực sự sẽ xử lý ngoại lệ bằng cách sử dụng Trình xử lý mặc định sẽ bỏ qua các cài đặt tùy chỉnhError của bạn.
Thiết lập này cho phép bạn đặt các thẻ ErrorHandler của riêng mình trong các lớp và chế độ xem, trong khi vẫn ghi nhật ký các lỗi đó thông qua ElmahMVCErrorFilter, thêm cấu hình customError vào web.config thông qua mô đun elmah, thậm chí viết Trình xử lý lỗi của riêng bạn. Điều duy nhất bạn cần làm là nhớ không thêm bất kỳ bộ lọc nào thực sự sẽ xử lý lỗi trước bộ lọc elmah mà chúng tôi đã viết. Và tôi quên đề cập: không có bản sao trong elmah.