2010-10-04 16 views
5

Tengo un control personalizado que se muestran sólo con un conjunto dado de valores de configuración.redirigiendo la salida Trace.axd

Quiero capturar los datos Trace.axd y salida a este control.

web.config

writeToDiagnosticsTrace="true" 
... 
<listeners> 
name="WebPageTraceListener" 
    type="System.Web.WebPageTraceListener, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
</listeners> 

Quiero ser capaz de cargar el archivo trace.axd en un control de usuario. Luego haga que se cargue el usercontrol siempre que sea necesario.

+0

¿Quieres decir el conjunto de solicitar detalles tablas, exactamente como salida Trace.axd ellos? ¿Cómo sería eso diferente de usar '' en su archivo 'web.config'? –

+0

Por ciertas razones, no podemos simplemente agregarlo a la página. Quién puede ver el rastro debe ser controlado. Así que he configurado todos los resultados en el webPageTrace, pero quiero controlar la salida. – Arnej65

+0

*** https: //msdn.microsoft.com/en-us/library/b0ectfxd.aspx *** ASP.NET muestra mensajes de rastreo cuando el rastreo está habilitado para una página. ('trace.axd TraceViewer') Para enrutar mensajes Trace a una página web ASP.NET, debe agregar un objeto' WebPageTraceListener'. Para ver los mensajes de seguimiento de ASP.NET y System.Diagnostics en un contexto fuera de una página ASP.NET, utilice un objeto 'TextWriterTraceListener' para escribir los mensajes de seguimiento en un archivo. – Kiquenet

Respuesta

3

tengo una solución de trabajo, con dos salvedades:

En primer lugar, siempre va a hacer que la salida de rastreo demasiado pronto, porque es demasiado tarde para hacer que en una anulación Page.ProcessRequest() (el objeto Response ya ha sido limpiado), por lo que estamos obligados a hacerlo durante la fase Render, lo que significa que perderemos algunos mensajes (sobre todo EndRender).

La implementación de ese comportamiento en un control agrava el problema, ya que tendríamos que asegurar que nuestro control sea lo último que se renderice en la página para evitar perder más mensajes. Por esa razón, elegí implementar una clase de página personalizada en lugar de una clase de control personalizada. Si necesitas absolutamente una clase de control, debería ser fácil de convertir (pero déjame una palabra aquí si necesitas ayuda).

En segundo lugar, el objeto de perfiles que posee los datos, HttpRuntime.Profile, es internal a la asamblea System.Web, y por supuesto la rutina renderizado traza es private a la clase Page. Así que tenemos que abusar de reflexión, romper la encapsulación, y básicamente ser el mal con el fin de hacer lo que quiera. Si la implementación del rastreo ASP.NET cambia en lo más mínimo, somos SOL.

Dicho esto, aquí está la clase de página trazable:

using System; 
using System.Reflection; 
using System.Web; 
using System.Web.UI; 

namespace StackOverflow.Bounties.Web.UI 
{ 
    public class TraceablePage : Page 
    { 
     /// <summary> 
     /// Gets or sets whether to render trace output. 
     /// </summary> 
     public bool EnableTraceOutput 
     { 
      get; 
      set; 
     } 

     /// <summary> 
     /// Abuses reflection to force the profiler's page output flag 
     /// to true during a call to the page's trace rendering routine. 
     /// </summary> 
     protected override void Render(HtmlTextWriter writer) 
     { 
      base.Render(writer); 
      if (!EnableTraceOutput) { 
       return; 
      } 

      // Allow access to private and internal members. 
      BindingFlags evilFlags 
       = BindingFlags.Instance | BindingFlags.Static 
       | BindingFlags.Public | BindingFlags.NonPublic; 

      // Profiler profiler = HttpRuntime.Profile; 
      object profiler = typeof(HttpRuntime) 
       .GetProperty("Profile", evilFlags).GetGetMethod(true) 
       .Invoke(null, null); 

      // profiler.PageOutput = true; 
      profiler.GetType().GetProperty("PageOutput", evilFlags) 
       .GetSetMethod(true).Invoke(profiler, new object[] { true }); 

      // this.ProcessRequestEndTrace(); 
      typeof(Page).GetMethod("ProcessRequestEndTrace", evilFlags) 
       .Invoke(this, null); 

      // profiler.PageOutput = false; 
      profiler.GetType().GetProperty("PageOutput", evilFlags) 
       .GetSetMethod(true).Invoke(profiler, new object[] { false }); 
     } 
    } 
} 

Y aquí está su página de prueba, que utiliza una caja de AutoPostBack verificación para demostrar su comportamiento a través de las devoluciones de datos:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestTracePage.aspx.cs" 
    Inherits="StackOverflow.Bounties.Web.UI.TestTracePage" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>TraceablePage Test</title> 
</head> 
<body> 
    <form id="form" runat="server"> 
    <h2>TraceablePage Test</h2> 
    <p> 
     <asp:CheckBox id="enableTrace" runat="server" 
      AutoPostBack="True" Text="Enable trace output" 
      OnCheckedChanged="enableTrace_CheckedChanged" /> 
    </p> 
    </form> 
</body> 
</html> 

Y el código subyacente :

using System; 
using System.Web.UI; 

namespace StackOverflow.Bounties.Web.UI 
{ 
    public partial class TestTracePage : TraceablePage 
    { 
     protected void enableTrace_CheckedChanged(object sender, EventArgs e) 
     { 
      EnableTraceOutput = enableTrace.Checked; 
     } 
    } 
} 

La página de prueba hace que este tipo en primera loa d:

Trace disabled

Comprobación de los mensajes de la caja de nuevo y hace que la salida de rastreo:

Trace enabled

Borrado de la casilla de verificación de nuevo suprime la salida de rastreo, como se esperaba.

Cuestiones relacionadas