【问题标题】:How do I retrieve response html from within a HttpModule?如何从 HttpModule 中检索响应 html?
【发布时间】:2010-11-25 17:14:19
【问题描述】:

这是我特别想做的事情:

我编写了一个 HttpModule 来进行一些特定于站点的跟踪。我们网站上的一些旧 .aspx 页面是硬编码的,没有真正的控件,但它们是 .aspx 文件,因此我的模块在被请求时仍会运行。

我的模块的处理程序附加到 PostRequestHandlerExecute,所以我相信应该已经确定了将发送回请求者的内容。

我需要能够提取标题标签中的任何字符串。

如果

<title>Chunky Bacon</title>

在最终呈现的 HTML 中发送给请求者。然后我想要“大块培根”。

想法?

【问题讨论】:

  • “提取标签中的任何字符串”是什么意思?您是否试图操纵发送回请求者的响应?目前尚不清楚您要做什么。
  • 对不起,我忘记了我的 HTML 标记不会显示,除非我将它分隔到一个代码块中。我不需要操作响应,只需提取标题标签内的字符串即可。
  • 澄清一下,您是尝试从响应中获取内容还是尝试从内容中解析标签?
  • 我正在尝试获取标题 html 标记的文本内容。如果这个 html 被发送到请求者的浏览器:Chunky Bacon 那么我想要“Chunky Bacon”

标签: c# asp.net html httpmodule


【解决方案1】:

有趣的小挑战。

代码如下:

StreamWatcher.cs

    public class StreamWatcher : Stream
    {
        private Stream _base;
        private MemoryStream _memoryStream = new MemoryStream();

        public StreamWatcher(Stream stream)
        {
            _base = stream;
        }

        public override void Flush()
        {
            _base.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _base.Read(buffer, offset, count);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _memoryStream.Write(buffer, offset, count);
            _base.Write(buffer, offset, count);
        }

        public override string ToString()
        {
            return Encoding.UTF8.GetString(_memoryStream.ToArray());
        }

        #region Rest of the overrides
        public override bool CanRead
        {
            get { throw new NotImplementedException(); }
        }

        public override bool CanSeek
        {
            get { throw new NotImplementedException(); }
        }

        public override bool CanWrite
        {
            get { throw new NotImplementedException(); }
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotImplementedException();
        }

        public override void SetLength(long value)
        {
            throw new NotImplementedException();
        }

        public override long Length
        {
            get { throw new NotImplementedException(); }
        }

        public override long Position
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
        #endregion
    }

TitleModule.cs

public class TitleModule : IHttpModule
{
    public void Dispose()
    {
    }

    private static Regex regex = new Regex(@"(?<=<title>)[\w\s\r\n]*?(?=</title)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    private StreamWatcher _watcher;
    public void Init(HttpApplication context)
    {
        context.BeginRequest += (o, e) => 
        {
            _watcher = new StreamWatcher(context.Response.Filter);
            context.Response.Filter = _watcher;
        };


        context.EndRequest += (o, e) =>
        {
            string value = _watcher.ToString();
            Trace.WriteLine(regex.Match(value).Value.Trim());
        };
    }
}

【讨论】:

  • 就是这样,谢谢broseph!我仍然非常惊讶这需要这么多行代码来执行......
  • 对于 4.6.1 AFAIK,您必须实现引发 NotImplementedException 的方法。最简单的方法当然是推迟所有对 _memoryStream 的调用
  • TitleModule 是 Application 范围内的单例。所以将_watcher 存储为TitleModule 的字段是一个坏主意,因为它可以在不同的请求之间共享。您不需要存储StreamWatcher,因为您将其分配给context.Response.Filter,您可以稍后从那里获取它。
【解决方案2】:

有一篇关于 4GuysFromRolla 的文章讨论了创建 HttpResponse 过滤器,这些过滤器基本上是在将响应传递到最终输出流(拦截器)之前处理响应的流。

http://aspnet.4guysfromrolla.com/articles/120308-1.aspx

【讨论】:

  • 酷,在寻找解决方案时,我在 google 上阅读了一些关于这些的内容,似乎编写其中一个的主要目的是在发送之前操纵发送的 HTML。由于我没有进行操作,只需要访问 HTML,我认为这将是矫枉过正,但如果这是唯一的方法......
猜你喜欢
  • 2023-03-15
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
  • 2012-10-16
  • 2021-01-18
  • 2018-06-13
  • 2011-04-22
  • 1970-01-01
相关资源
最近更新 更多