如何最好地捕获aspx页面呈现的HTML(在我的实例中,用于记录)?
我不想使用Response.Write回写页面,因为它会弄乱我的网站布局。
使用Response.OutputStream或Response.Output的流导致ArgumentException({System.ArgumentException:Stream无法读取。)
答案 0 :(得分:25)
好问题,我必须尝试一下,看看我是否可以创建一个HttpModule来完成你所描述的内容。
我没有尝试从响应流中读取任何运气,但使用ResponseFilter为我提供了捕获内容的方法。
以下代码似乎工作得很好,我想也许你可以使用代码作为基础。但请记住,这只是我快速拼凑的东西,它没有经过任何方式的测试。因此,如果没有适当的审查/测试等,请不要在任何生产环境中使用它。尽管如此,请随意评论;)
public class ResponseLoggerModule : IHttpModule
{
private class ResponseCaptureStream : Stream
{
private readonly Stream _streamToCapture;
private readonly Encoding _responseEncoding;
private string _streamContent;
public string StreamContent
{
get { return _streamContent; }
private set
{
_streamContent = value;
}
}
public ResponseCaptureStream(Stream streamToCapture, Encoding responseEncoding)
{
_responseEncoding = responseEncoding;
_streamToCapture = streamToCapture;
}
public override bool CanRead
{
get { return _streamToCapture.CanRead; }
}
public override bool CanSeek
{
get { return _streamToCapture.CanSeek; }
}
public override bool CanWrite
{
get { return _streamToCapture.CanWrite; }
}
public override void Flush()
{
_streamToCapture.Flush();
}
public override long Length
{
get { return _streamToCapture.Length; }
}
public override long Position
{
get
{
return _streamToCapture.Position;
}
set
{
_streamToCapture.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
return _streamToCapture.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _streamToCapture.Seek(offset, origin);
}
public override void SetLength(long value)
{
_streamToCapture.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_streamContent += _responseEncoding.GetString(buffer);
_streamToCapture.Write(buffer, offset, count);
}
public override void Close()
{
_streamToCapture.Close();
base.Close();
}
}
#region IHttpModule Members
private HttpApplication _context;
public void Dispose()
{
}
public void Init(HttpApplication context)
{
_context = context;
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
context.PreSendRequestContent += new EventHandler(context_PreSendRequestContent);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
_context.Response.Filter = new ResponseCaptureStream(_context.Response.Filter, _context.Response.ContentEncoding);
}
void context_PreSendRequestContent(object sender, EventArgs e)
{
ResponseCaptureStream filter = _context.Response.Filter as ResponseCaptureStream;
if (filter != null)
{
string responseText = filter.StreamContent;
// Logging logic here
}
}
#endregion
}
答案 1 :(得分:4)
许多负载测试人员将允许您记录生成的HTTP响应,但请记住,那些可能是一些非常大的日志文件。
编辑:Response.Filter根据Tom Jelen的代码旨在提供这种疏忽,而Response.Outputstream则无法读取。
编辑2:对于页面而不是HTTPModule
public class ObserverStream : Stream
{
private byte[] buffer = null;
private Stream observed = null;
public ObserverStream (Stream s)
{
this.observed = s;
}
/* important method to extend #1 : capturing the data */
public override void Write(byte[] buffer, int offset, int count)
{
this.observed.Write(buffer, offset, count);
this.buffer = buffer; //captured!
}
/* important method to extend #2 : doing something with the data */
public override void Close()
{
//this.buffer available for logging here!
this.observed.Close();
}
/* override all the other Stream methods/props with this.observed.method() */
//...
}
并在你的Page_Load中(或在你的回复被写入之前)
Response.Filter = new ObserverStream(Response.Filter);
答案 2 :(得分:1)
向您自己的服务器发出服务器端XMLHTTP请求的一种方法。抓取结果并将其保存到文件或数据库中。
或者,您可以在客户端上使用AJAX,获取结果,然后将其POST回服务器。