Asp.net-Mvc

呼叫 .Raise() 後獲取 Elmah 中的錯誤 ID

  • March 31, 2017

我正在開發一個 MVC3 應用程序,我正在使用 Elmah 來處理我的錯誤日誌記錄。我想要在我的應用程序中將 Elmah Id 攜帶到自定義錯誤頁面上,因為我將提供一個連結,允許使用者在它是重複錯誤的情況下專門報告它(在他們看來)。

現在,我在這裡閱讀了類似的問題,他們建議將以下程式碼(或類似程式碼)添加到 Global.asax.cs 文件中:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
   string sessionId = Session.SessionID;
   Session["ElmahId_" + sessionId] = args.Entry.Id;
}

這就是我目前正在使用的,SessionID 允許在使 Session 儲存對象唯一時增加靈活性。但是,如果(幾乎)同時發生多個錯誤,這仍可能會導致問題。

相反,我決定使用我自己的 HandleErrorAttribute,它看起來像這樣:

public class ElmahHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
   public void OnException(ExceptionContext filterContext)
   {
       if (filterContext == null)
           throw new ArgumentNullException("filterContext");

       if (filterContext.IsChildAction && (!filterContext.ExceptionHandled
           && filterContext.HttpContext.IsCustomErrorEnabled))
       {
           Elmah.ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);

           // get error id here
           string errorId = null;

           string areaName = (String)filterContext.RouteData.Values["area"];
           string controllerName = (String)filterContext.RouteData.Values["controller"];
           string actionName = (String)filterContext.RouteData.Values["action"];

           var model = new ErrorDetail
           {
               Area = areaName,
               Controller = controllerName,
               Action = actionName,
               ErrorId = errorId,
               Exception = filterContext.Exception
           };

           ViewResult result = new ViewResult
           {
               ViewName = "Error",,
               ViewData = new ViewDataDictionary<ErrorDetail>(model),
               TempData = filterContext.Controller.TempData
           };

           filterContext.Result = result;
           filterContext.ExceptionHandled = true;
           filterContext.HttpContext.Response.Clear();
           filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
       }
   }
}

其中 ErrorDetail 是一個自定義模型,它僅具有在此處設置為字元串的公共屬性。然後可以在模型中快速顯示此數據以供管理員快速瀏覽,並且 errorId 可用於創建“報告錯誤”連結。

所以我的問題是有沒有人知道線上路後獲取 ID 的方法

Elmah.ErrorSignal.FromCurrentContext().Raise(filterContext.Exception)

不使用 global.asax.cs 中的 Logged 事件?

任何想法都非常感謝。

在閱讀了 Dupin 的評論之後,這似乎不太可能是合乎邏輯的。我嘗試探勘 Elmah 原始碼並提出了一些可能值得分享的替代方案。

顯而易見的替代方法是堅持使用 Logged 事件的原始選項:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
   string sessionId = Session.SessionID;
   Session["ElmahId_" + sessionId] = args.Entry.Id;
}

對於更直接的解決方案,可以使用以下內容手動記錄錯誤:

string errorId = Elmah.ErrorLog.GetDefault(HttpContext.Current)
   .Log(new Elmah.Error(filterContext.Exception));

但是,使用這種方法不會影響您的過濾器或郵件模組等。

經過一番思考和更多搜尋後,我想出了一個新的折衷方案。仍在使用記錄的事件,但我找到了一種方法來創建一個可以傳遞給視圖的新唯一鍵,方法是將我自己的數據添加到異常中。

string loggingKey = "ElmahId_" + Guid.NewGuid().ToString();
filterContext.Exception.Data.Add("LoggingKey", loggingKey);

這樣我就可以在我的視圖模型中傳遞異常,它在數據集合中有這個鍵值。記錄的事件將更改為如下內容:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
   string key = args.Entry.Error.Exception.Data["LoggingKey"].ToString();
   Session[key] = args.Entry.Id;
}

然後在視圖中,我從模型中獲取密鑰,然後從 Session 集合中提取 Id。

引用自:https://stackoverflow.com/questions/7895271