重定向Trace.axd输出

Arn*_*j65 5 c# debugging .net-3.5

我有一个自定义控件,只显示给定的一组配置值.

我想捕获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>
Run Code Online (Sandbox Code Playgroud)

我希望能够在usercontrol中加载trace.axd文件.然后在需要时加载该usercontrol.

Fré*_*idi 3

我有一个可行的解决方案,但有两个警告:

首先,它总是会太早渲染跟踪输出,因为在Page.ProcessRequest()重写中执行此操作为时已晚(Response对象已被清理),因此我们被迫在该Render阶段执行此操作,这意味着我们会错过一些消息(最值得注意的是EndRender)。

在控件中实现该行为会加剧问题,因为我们必须确保控件是页面上最后呈现的内容,以避免丢失更多消息。因此,我选择实现自定义页面类而不是自定义控件类。如果您绝对需要一个控制类,那么它应该很容易转换(但如果您需要帮助,请在这里留言)。

其次,拥有数据的探查器对象HttpRuntime.Profileinternal程序System.Web集,当然跟踪渲染例程是privatePage。因此,我们必须滥用反射,破坏封装,并且基本上是邪恶的,以便做你想做的事。如果 ASP.NET 跟踪实现有丝毫变化,我们就可以解决。

也就是说,这是可追踪的页面类:

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 });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是它的测试页面,它使用一个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>
Run Code Online (Sandbox Code Playgroud)

以及背后的代码:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试页面在第一次加载时呈现如下:

跟踪已禁用

选中该框回发并呈现跟踪输出:

启用跟踪

正如预期的那样,再次清除该复选框会抑制跟踪输出。