如何将跟踪输出添加到httphandler中的context.response?

时间:2009-07-24 20:20:32

标签: asp.net httphandler trace system.diagnostics

我在web.config中启用了trace pageoutput =“true”,我喜欢在页面底部看到所有这些内容的简单方法。

我想从httpsndler的输出底部获取跟踪的相同输出。有没有办法通过代码遵循此代码转储相同的跟踪信息:

public class UploadHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

我特别想看看Forms和QueryString集合,但所有这些都是“Hello World”。

- 编辑更新7/25/2009:

    public class UploadHandler : IHttpHandler
    {

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");

        object htw = new System.Web.UI.Html32TextWriter(context.Response.Output);
        {
            typeof(TraceContext)
                .GetMethod("Render", System.Reflection.BindingFlags.NonPublic)
                .Invoke(HttpContext.Current.Trace, new object[] { htw });
        }

    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

我也欢迎任何其他关于如何最轻松地获取表单和查询字符串集合的格式化转储的想法,如pageOutput trace。

3 个答案:

答案 0 :(得分:1)

您可以从HttpContext.Current.Trace.TraceFinished获取自己的跟踪事件。不幸的是,页面跟踪(包括Forms,QueryString等所有好东西)在内部方法中被锁定。

如果您对反射没问题,可以这样称呼:

using (var htw = new System.Web.UI.Html32TextWriter(response.Output)) {
    typeof(TraceContext)
        .GetMethod("Render",BindingFlags.NonPublic | BindingFlags.Instance)
        .Invoke(HttpContext.Current.Trace, new object[] { htw });
}

如果你不能使用反射,那么反射System.Web.TraceContext.EndRequest就足以让你创建自己的TracingHttpHandler

编辑: 看起来你忘记了BindingFlags.Instance。此外,我猜你已将using (var htw = ...)更改为using (object htw = ...),这会给你“类型必须隐式转换为IDisposable”错误。如果您无法使用var,那么您必须将其写为using (Html32TextWriter htw = ...)

完整样本:

<%@ WebHandler Language="C#" Class="UploadHandler" %>

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

public class UploadHandler : IHttpHandler {
    public bool IsReusable { 
       get { return true; }
    }

    public void ProcessRequest(HttpContext context) {
       // the output will suck as text/plain - Render outputs HTML.
       context.Response.ContentType = "text/html"; 
       context.Response.Write("Hello World!");

       // depending on web.config settings, you may need to enable tracing manually
       HttpContext.Current.Trace.IsEnabled = true;
       // I had to write a custom trace message, or the Request context wasn't captured - YMMV
       HttpContext.Current.Trace.Write(null);

       using (Html32TextWriter htw = new Html32TextWriter(context.Response.Output)) {
          typeof(TraceContext)
              .GetMethod("Render", BindingFlags.NonPublic | BindingFlags.Instance)
             .Invoke(HttpContext.Current.Trace, new object[] { htw });
       } 
    }
}

答案 1 :(得分:0)

我认为除了页面之外,ASP.NET跟踪无效。

输出是否位于页面底部是否重要?如果输出位于单独的文件中,或者在事件日志中,该怎么办?您可以使用ASP.NET Health Monitoring进行操作。

答案 2 :(得分:0)

实际上,只要您拥有正确的异常类型,从ASP.Net获取此信息非常简单。我在我的global.asax错误处理程序中使用这个MVC应用程序向我发送死亡堆栈跟踪的黄色屏幕,我通常不会看到;

        // See if ASP.Net has some error handling info for us first
        string htmlError = null;
        var httpException = e as HttpException;
        if (httpException != null)
            htmlError = httpException.GetHtmlErrorMessage();
        else
        {
            // Ok, we'll generate our own then
            var h = new HttpUnhandledException(e.Message, e);
            htmlError = h.GetHtmlErrorMessage();
        }

请注意,在第二个语句组中,我简单地包装了在HttpUnhandledException()中抛出的任何异常,它具有适当的方法和gunk来收集并吐出所有的好东西。