2009-12-29 3 views
9

HINWEIS: Ich kenne die verschiedenen Gründe zu vermeiden, die Sitzung zu verwenden, aber das ist ein Projekt, das ich geerbt habe, also bitte überspringen Sie diesen Teil der Antworten :)Wie bekomme ich ELMAH um Sitzungswerte aufzunehmen?

Da es ein gelöstes Problem ist, hoffe ich jemand kann auf ein ELMAH-Patch/eine Verzweigung/Verzweigung verweisen, die Protokollierungssitzungsdaten enthält, anstatt das Rad neu zu erfinden.

Eine seltsame Sache ist, ein älterer Beitrag von Atif, die sagt, sie sind bereits angemeldet:

http://markmail.org/message/ncmdgwm5rmzewbwu

Kommentator henningst hier in den Session-Variablen erwähnt Zugabe:

http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx

Another Ansatz (ich würde eher vermeiden) ist das Kopieren der Werte in Cookies

http://www.sharpdeveloper.net/content/archive/2008/11/10/how-to-get-session-or-other-custom-values-into-elmah.aspx

Ich kenne eine Alternative zu etwas außer ELMAH zu wechseln ist (wie Exceptioneer - siehe http://exceptioneer.com/Public/ExceptioneerAndELMAH.aspx), aber da dieses mit ELMAH im Moment mein einziges Problem ist, würde ich lieber nur eine gepatchte ELMAH als Schalter, um etwas sonst.

Antwort

3

Anstatt Patchen Elmah, ich habe das mit Ausnahmedaten gemacht. In Global.asax habe ich die zusätzlichen Daten in die Ausnahme in Application_Error() eingefügt. "HistoryStack" ist meine eigene Klasse für die Benutzergeschichte Aufzeichnung, einschließlich Taste und Tab Klicks:

void Application_Error(object sender, EventArgs e) 
{ 
    Exception ex = Server.GetLastError().GetBaseException(); 
    var stack = HistoryStack.Dump(); // essentially grabs data from the session 
    ex.Data.Add("historyStack", stack); 
} 

Dann in ErrorMail_Mailing() ich die Daten wieder gepackt und hängten es in der E-Mail:

void ErrorMail_Mailing(object sender, Elmah.ErrorMailEventArgs e) 
{ 
    var stack = e.Error.Exception.Data["historyStack"] as Stack<string>; 
    if (stack == null && e.Error.Exception.InnerException != null) 
    { 
     // could probably skip the first try and go straight to this assignment: 
     stack = e.Error.Exception.InnerException.Data["historyStack"] as Stack<string>; 
    } 

    if (stack != null && stack.Count > 0) 
    { 
     e.Mail.Body = e.Mail.Body + "<h1>Browsing History</h1>" + System.Environment.NewLine; 
     while (stack.Count > 0) 
     { 
      e.Mail.Body = e.Mail.Body + stack.Pop() + "<br />" + System.Environment.NewLine; 
     } 
    } 
} 

Jetzt werden diese Daten an den unteren Rand der E-Mail angehängt. Keine Patches oder Erweiterungen notwendig.

+0

Dies ist im Wesentlichen was ich auch tat, außer dass ich eine Anlage an die E-Mail zu schaffen, um Sitzungsvariablen ein wenig getrennt zu halten. Der Nachteil ist, dass Sie auf das ELMAHs Mailing-Modul tippen, also wenn es jemanden gibt, der es nicht benutzt, sind sie toast + Sie können Ihre Datenbank nicht abfragen, um Statistiken über diese Variablen zu erhalten. – lstanczyk

+0

Welches Format hat der zurückgegebene Wert von HistoryStack.Dump()? Ist es nur CRLF-Klartext? – NickG

+0

Das scheint bei mir nicht zu funktionieren. Obwohl Application_Error() ausgelöst wird, scheinen die zusätzlichen Daten nie in der XML in der Datenbank zu landen, also gibt es keine Möglichkeit, sie anzuzeigen :(Ist irgendwo ein zusätzlicher Schritt erforderlich? – NickG

0

Der alte Patch, der ausgegraben werden kann, ist leider mit Elmah jetzt ein wenig veraltet. Hier ist, was ich tat, Session-Variablen in Version 2.0.15523.27 Basierend auf einem älteren Patch hier anmelden: https://storage.googleapis.com/google-code-attachments/elmah/issue-12/comment-5/elmah-sessionVariables.patch

In Error.cs

Import System.Web.Session

using System.Web.SessionState; 

Suche:

private NameValueCollection _serverVariables; 
private NameValueCollection _queryString; 
private NameValueCollection _form; 
private NameValueCollection _cookies; 

unten hinzufügen:

private NameValueCollection _sessionVariables; 

Suche:

_serverVariables = CopyCollection(request.ServerVariables); 
_queryString = CopyCollection(qsfc.QueryString); 
_form = CopyCollection(qsfc.Form); 
_cookies = CopyCollection(qsfc.Cookies); 

unten hinzufügen:

_sessionVariables = CopyCollection(context.Session); 

Suche:

public NameValueCollection Cookies 
{ 
    get { return FaultIn(ref _cookies); } 
} 

unten hinzufügen:

/// <summary> 
/// Gets a collection representing the session variables captured as part of the diagnostic data 
/// </summary> 

public NameValueCollection SessionVariables 
{ 
    get { return FaultIn(ref _sessionVariables); } 
} 

Suche:

copy._serverVariables = CopyCollection(_serverVariables); 
copy._queryString = CopyCollection(_queryString); 
copy._form = CopyCollection(_form); 
copy._cookies = CopyCollection(_cookies); 

hinzufügen unten:

copy._sessionVariables = CopyCollection(_sessionVariables); 

Suche:

private static NameValueCollection CopyCollection(NameValueCollection collection) 

oben hinzufügen:

private static NameValueCollection CopyCollection(HttpSessionStateBase sessionVariables) 
{ 
    if (sessionVariables == null || sessionVariables.Count == 0) 
     return null; 

    var copy = new NameValueCollection(sessionVariables.Count); 

    for (int i = 0; i < sessionVariables.Count; i++) 
     copy.Add(sessionVariables.Keys[i], sessionVariables[i].ToString()); 

    return copy; 
} 

In ErrorJson.cs

Suche:

Member(writer, "queryString", error.QueryString); 
Member(writer, "form", error.Form); 
Member(writer, "cookies", error.Cookies); 

unten hinzufügen:

Member(writer, "sessionVariables", error.SessionVariables); 

In ErrorXml.cs

Suche:

case "form"   : collection = error.Form; break; 
case "cookies"   : collection = error.Cookies; break; 

unten hinzufügen:

case "sessionVariables": collection = error.SessionVariables; break; 

Suche:

WriteCollection(writer, "form", error.Form); 
WriteCollection(writer, "cookies", error.Cookies); 

unten hinzufügen:

WriteCollection(writer, "sessionVariables", error.SessionVariables); 

In ErrorMailHtmlPage.cshtml

Suche:

<p>@(RenderPartial<PoweredBy>())</p> 

oben hinzufügen:

@foreach (var collection in 
    from collection in new[] 
    { 
     new 
     { 
      Id = "SessionVariables", 
      Title = "Session Variables", 
      Items = error.SessionVariables, 
     } 
    } 
    let data = collection.Items 
    where data != null && data.Count > 0 
    let items = from i in Enumerable.Range(0, data.Count) 
     select KeyValuePair.Create(data.GetKey(i), data[i]) 
    select new 
    { 
     collection.Id, 
     collection.Title, 
     Items = items.OrderBy(e => e.Key, StringComparer.OrdinalIgnoreCase) 
    } 
    ) 
{ 
    <div id="@collection.Id"> 
     <h1>@collection.Title</h1> 
     <table class="collection"> 
      <tr><th>Name</th>    
       <th>Value</th></tr> 
      @foreach (var item in collection.Items) 
      { 
       <tr><td>@item.Key</td> 
        <td>@item.Value</td></tr> 
      } 
     </table> 
    </div> 
} 

Nach Änderungen an ErrorMailHtmlPage.cshtml in Visual Studio zu machen, klicken Sie rechts auf die Datei und "Run Custom Tool" die erzeugen Code für ErrorMailHtmlPage.generated.cs


In ErrorDetailPage.cshtml

Suche (am Ende der Datei):

@* 
} 
*@ 

oben hinzufügen:

@{ 
    var sessioncollection = new 
    { 
     Data = error.SessionVariables, 
     Id = "SessionVariables", 
     Title = "Session Variables", 
    }; 

    // 
    // If the collection isn't there or it's empty, then bail out. 
    // 

    if (sessioncollection.Data != null && sessioncollection.Data.Count > 0) 
    { 
     var items = 
      from i in Enumerable.Range(0, sessioncollection.Data.Count) 
      select new 
      { 
       Index = i, 
       Key = sessioncollection.Data.GetKey(i), 
       Value = sessioncollection.Data[i], 
      }; 

     items = items.OrderBy(e => e.Key, StringComparer.OrdinalIgnoreCase); 

     <div id="@sessioncollection.Id"> 

      <h2>@sessioncollection.Title</h2> 
      @* 
       // Some values can be large and add scroll bars to the page 
       // as well as ruin some formatting. So we encapsulate the 
       // table into a scrollable view that is controlled via the 
       // style sheet. 
      *@ 

      <div class="scroll-view"> 

       <table cellspacing="0" style="border-collapse:collapse;" class="table table-condensed table-striped"> 
        <tr> 
         <th class="name-col" style="white-space:nowrap;">Name</th> 
         <th class="value-col" style="white-space:nowrap;">Value</th> 
        </tr> 

        @foreach (var item in items) 
        { 
         <tr class="@(item.Index % 2 == 0 ? "even" : "odd")"> 
          <td class="key-col">@item.Key</td> 
          <td class="value-col">@item.Value</td> 
         </tr> 
        } 

       </table> 
      </div> 
     </div> 
    } 
} 

Nach Änderungen an ErrorDetailPage.cshtml in Visual Studio, Rechtsklick machen auf der Datei und "Run Custom Tool", um den Code für ErrorDetailPage.generated.cs

generieren

Jetzt können Sie erstellen (ich habe nur die Datei build.cmd verwendet, die mit dem Projekt enthalten war) und die ddl-Dateien aus bin, die benötigt werden.

  • AntiXssLibrary.dll
  • Elmah.AspNet.dll
  • Elmah.dll

Sie können auch haben die web.config in einem Projekt ändern jetzt die Version enthalten auf irgendwelche Hinweise auf Elmah. Wenn Sie Resharper verwenden, können Sie einfach auf jede dieser Komponenten klicken und sie reparieren. (Es gibt wahrscheinlich eine andere Möglichkeit, dies soll getan werden, um dies zu vermeiden, aber ich bin nicht sicher, und ich war nicht allzu besorgt darüber herauszufinden)

Ein Beispiel einer von ihnen, obwohl

sich ändern
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" /> 

zu

<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah.AspNet, Version=2.0.15523.27, Culture=neutral, PublicKeyToken=null" />