Domanda

NOTA: so che le varie ragioni per evitare di utilizzare la sessione, ma questo è un progetto che ho ereditato, quindi si prega di saltare quella parte di eventuali repliche:)

Dal momento che è un problema risolto, sto sperando che qualcuno può puntare a una patch ELMAH / filiale / forchetta che include la registrazione dei dati di sessione piuttosto che reinventare la ruota.

Una cosa strana è un vecchio post di Atif che dice che stanno già registrato:

http://markmail.org/message/ncmdgwm5rmzewbwu

commentatore henningst menzionato aggiungendo le variabili di sessione qui:

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

Un altro approccio (Preferirei evitare) è la copia dei valori in cookie

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

So che un'alternativa è quella di passare a qualcosa oltre ELMAH (come Exceptioneer - vedi http: // exceptioneer. com / pubblico / ExceptioneerAndELMAH.aspx ), ma dal momento che questo è il mio unico problema con ELMAH al momento, preferirei solo hanno un ELMAH patch di passare a qualcos'altro.

È stato utile?

Altri suggerimenti

Invece di patch Elmah, ho fatto questo con i dati di eccezione. In Global.asax ho inserito i dati aggiuntivi nel l'eccezione sulla Application_Error (). "HistoryStack" è la mia classe per registrare la storia utente, tra cui pulsanti e scheda Clic:

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);
}

Poi, in ErrorMail_Mailing () Ho afferrato i dati avanti e aggiunti nella 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;
        }
    }
}

Ora questi dati viene aggiunto al fondo all'e-mail. Nessuna patch o estensioni necessarie.

Il vecchio cerotto che può essere scavato è, purtroppo, un po 'datato con Elmah ora. Ecco quello che ho fatto per registrare le variabili di sessione in versione 2.0.15523.27 Sulla base di una patch più vecchio trovato qui: https://storage.googleapis.com/google-code-attachments/elmah/issue-12/comment-5/elmah-sessionVariables.patch

In Error.cs

Importa System.Web.SessionState

using System.Web.SessionState;

Ricerca:

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

Aggiungi al di sotto:

private NameValueCollection _sessionVariables;

Ricerca:

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

Aggiungi al di sotto:

_sessionVariables = CopyCollection(context.Session);

Ricerca:

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

Aggiungi al di sotto:

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

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

Ricerca:

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

Aggiungi al di sotto:

copy._sessionVariables = CopyCollection(_sessionVariables);

Ricerca:

private static NameValueCollection CopyCollection(NameValueCollection collection)

Aggiungi sopra:

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

Ricerca:

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

Aggiungi al di sotto:

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

In ErrorXml.cs

Ricerca:

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

Aggiungi al di sotto:

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

Ricerca:

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

Aggiungi al di sotto:

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

In ErrorMailHtmlPage.cshtml

Ricerca:

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

Aggiungi sopra:

@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>
}

Dopo aver apportato le modifiche al ErrorMailHtmlPage.cshtml in Visual Studio, fare clic destro sul file e "Esegui strumento personalizzato" per generare il codice per ErrorMailHtmlPage.generated.cs


In ErrorDetailPage.cshtml

Find (alla fine del file):

@*
}
*@

Aggiungi sopra:

@{
    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>
    }
}

Dopo aver apportato le modifiche al ErrorDetailPage.cshtml in Visual Studio, fare clic destro sul file e "Esegui strumento personalizzato" per generare il codice per ErrorDetailPage.generated.cs


Ora è possibile costruire (ho appena usato il file build.cmd che è stato incluso con il progetto) e afferrare i file DDL da raccoglitore che sono necessari.

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

Si può anche essere necessario modificare il web.config nel progetto ora di includere la versione su eventuali riferimenti a Elmah. Se stai usando ReSharper è sufficiente fare clic su ciascuno di questi e correggerli. (C'è probabilmente un modo diverso questo dovrebbe essere fatto per evitare questo, ma non sono sicuro e non ero troppo preoccupato per capire che fuori)

Un esempio di uno di loro se sarebbero cambiando

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

a

<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah.AspNet, Version=2.0.15523.27, Culture=neutral, PublicKeyToken=null" />
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top