Pregunta

NOTA: Se que las diversas razones para evitar el uso de la sesión, pero este es un proyecto que he heredado, así que por favor omitir esa parte de respuestas:)

Ya que es un problema resuelto, estoy esperando que alguien puede apuntar a un parche ELMAH / sucursal / tenedor que incluye el registro de datos de sesión en lugar de reinventar la rueda.

Una cosa rara es un mensaje más antiguo de Atif que dice que ya estás conectado:

http://markmail.org/message/ncmdgwm5rmzewbwu

henningst comentarista mencionó la adición de las variables de sesión aquí:

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

Otro enfoque (que prefiero evitar) está copiando los valores en las cookies

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

Sé que una alternativa es cambiar a algo más que ELMAH (como Exceptioneer - veo http: // exceptioneer. com / público / ExceptioneerAndELMAH.aspx ) pero ya que este es mi único problema con ELMAH por el momento, prefiero simplemente una ELMAH parcheado que cambiar a otra cosa.

¿Fue útil?

Otros consejos

En lugar de parchear Elmah, lo hice con los datos de excepción. En Global.asax me inserta los datos adicionales en la excepción de Application_Error (). "HistoryStack" es mi propia clase para registrar el historial del usuario, incluyendo los botones y la lengüeta de clics:

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

Luego, en ErrorMail_Mailing () Me agarró la parte posterior de datos y anexa que en el correo electrónico:

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

Ahora estos datos se añade al final del correo electrónico. No hay parches o extensiones necesarias.

El viejo parche que puede ser excavado por desgracia es un poco anticuado, con Elmah ahora. Esto es lo que hice para registrar las variables de sesión en la versión 2.0.15523.27 Basado en un parche más viejo conocer aquí: https://storage.googleapis.com/google-code-attachments/elmah/issue-12/comment-5/elmah-sessionVariables.patch

En Error.cs

Importar System.Web.SessionState

using System.Web.SessionState;

Para:

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

Añadir a continuación:

private NameValueCollection _sessionVariables;

Para:

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

Añadir a continuación:

_sessionVariables = CopyCollection(context.Session);

Para:

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

Añadir a continuación:

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

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

Para:

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

Añadir a continuación:

copy._sessionVariables = CopyCollection(_sessionVariables);

Para:

private static NameValueCollection CopyCollection(NameValueCollection collection)

Añadir anterior:

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

En ErrorJson.cs

Para:

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

Añadir a continuación:

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

En ErrorXml.cs

Para:

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

Añadir a continuación:

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

Para:

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

Añadir a continuación:

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

En ErrorMailHtmlPage.cshtml

Para:

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

Añadir anterior:

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

Tras realizar cambios en ErrorMailHtmlPage.cshtml en Visual Studio, haga clic derecho sobre el archivo y "Herramienta personalizada Ejecutar" para generar el código para ErrorMailHtmlPage.generated.cs


En ErrorDetailPage.cshtml

Encuentra (al final del archivo):

@*
}
*@

Añadir anterior:

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

Tras realizar cambios en ErrorDetailPage.cshtml en Visual Studio, haga clic derecho sobre el archivo y "Herramienta personalizada Ejecutar" para generar el código para ErrorDetailPage.generated.cs


Ahora usted puede construir (acabo de utilizar el archivo build.cmd que se incluye con el proyecto) y agarrar los archivos DDL de la papelera que se necesitan.

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

También es posible que tenga que modificar el web.config en su proyecto ahora para incluir la versión en cualquier referencia a Elmah. Si está utilizando ReSharper que sólo puede hacer clic en cada uno de ellos y corregirlos. (Probablemente hay una manera diferente esto se supone que hay que hacer para evitar esto, pero no estoy seguro y no estaba demasiado preocupado por averiguarlo)

Un ejemplo de uno de ellos, aunque sería cambiar

<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" />
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top