我该如何最好地捕获aspx页面呈现的HTML(在我的情况下,用于记录)?
我不想使用Response.Write向页面写回,因为它会破坏我的网站布局。
使用Response.OutputStream或Response.Output的流会导致ArgumentException ({System.ArgumentException: Stream was not readable.)
我该如何最好地捕获aspx页面呈现的HTML(在我的情况下,用于记录)?
我不想使用Response.Write向页面写回,因为它会破坏我的网站布局。
使用Response.OutputStream或Response.Output的流会导致ArgumentException ({System.ArgumentException: Stream was not readable.)
很好的问题,我尝试并想知道是否可以创建一个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
}
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);
一种在服务器端发起XMLHTTP请求的方法是向自己的服务器发送请求。获取结果并将其保存到文件或数据库中。
另一种方法是在客户端使用AJAX,获取结果,并将其POST回服务器。