2010-10-04 145 views
5

我有一個自定義控件只顯示給定的一組配置值。重定向Trace.axd輸出

我想捕獲trace.axd數據並將其輸出到此控件。

的web.config

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

我希望能夠加載的trace.axd文件中的一個usercontrol。然後在需要時加載該用戶控件。

+0

您的意思是整個請求細節表,完全像Trace.axd一樣輸出它們嗎?這與在'web.config'文件中使用''有什麼不同? – 2010-10-26 18:17:16

+0

由於某些原因,我們不能將其添加到頁面。誰能看到需要控制的痕跡。所以我已將所有輸出設置爲webPageTrace,但要控制輸出。 – Arnej65 2010-10-26 19:30:38

+0

*** https://msdn.microsoft.com/en-us/library/b0ectfxd。aspx *** 只要對頁面啓用跟蹤,ASP.NET就會顯示跟蹤消息。 ('trace.axd TraceViewer') 要將跟蹤消息路由到ASP.NET網頁,您必須添加一個'WebPageTraceListener'對象。 要在ASP.NET頁面外的上下文中查看ASP.NET和System.Diagnostics跟蹤消息,請使用「TextWriterTraceListener」對象將跟蹤消息寫入文件。 – Kiquenet 2016-05-05 08:53:22

回答

3

我有一個有效的解決方案,有兩個注意事項:

首先,它總是呈現跟蹤輸出太早,因爲它是來不及做,在一個Page.ProcessRequest()補償(Response對象已被清理),所以我們不得不在Render階段這樣做,這意味着我們會錯過一些消息(最明顯的是EndRender)。

在控件中實現該行爲會加劇問題,因爲我們必須確保我們的控件是在頁面上呈現的最後一件東西,以避免丟失更多消息。出於這個原因,我選擇實現自定義頁面類而不是自定義控件類。如果你絕對需要一個控制類,轉換應該很容易(但是如果你需要幫助,可以在這裏留言)。

其次,擁有該數據,HttpRuntime.Profile探查對象,是internalSystem.Web組件,當然跟蹤渲染程序是privatePage類。所以我們不得不濫用反射,打破封裝,基本上是邪惡爲了做你想做的。如果ASP.NET跟蹤實現稍有變化,我們就是SOL。

這就是說,這裏的可追溯頁面類:

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

下面是它的測試頁,它使用一個AutoPostBack複選框,以展示其在回發的行爲:後邊

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

和代碼:

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

測試頁在第一個loa上呈現這樣的樣子d:

Trace disabled

檢查框回發,並呈現跟蹤輸出:

Trace enabled

再次清除該複選框抑制跟蹤輸出,符合市場預期。