Rya*_*lor 8 c# flush stream httpresponse filter
正如其他几篇文章中所述(请参阅下面的参考资料)我试图创建响应过滤器,以便修改由另一个Web应用程序生成的内容.
我将基本的字符串转换逻辑工作并封装到源自公共FilterBase的Filters中.但是,逻辑必须对完整内容进行操作,而不是对内容进行操作.因此,我需要在写入时缓存块,并在完成所有写入时执行过滤器.
如下所示,我创建了一个从MemoryStream派生的新ResponseFilter.在写入时,内容缓存到另一个MemoryStream.在Flush上,现在在MemoryStream中的完整内容将转换为字符串,并且Filter逻辑将启动.然后将修改后的内容写回原始流.
但是,在每个第二个请求(基本上当一个新的过滤器在前一个过滤器上实例化)时,正在执行前一个过滤器的Flush方法.此时,由于_cachedStream为空,应用程序在_outputStream.Write()方法上崩溃.
活动顺序如下:
我有几个问题:
注意:如果我不重写Close方法,我会遇到完全相同的行为(减去Close事件).
public class ResponseFilter : MemoryStream
{
private readonly Stream _outputStream;
private MemoryStream _cachedStream = new MemoryStream(1024);
private readonly FilterBase _filter;
public ResponseFilter (Stream outputStream, FilterBase filter)
{
_outputStream = outputStream;
_filter = filter;
}
// Flush is called on the second, fourth, and so on, page request (second request) with empty content.
public override void Flush()
{
Encoding encoding = HttpContext.Current.Response.ContentEncoding;
string cachedContent = encoding.GetString(_cachedStream.ToArray());
// Filter the cached content
cachedContent = _filter.Filter(cachedContent);
byte[] buffer = encoding.GetBytes(cachedContent);
_cachedStream = new MemoryStream();
_cachedStream.Write(buffer, 0, buffer.Length);
// Write new content to stream
_outputStream.Write(_cachedStream.ToArray(), 0, (int)_cachedStream.Length);
_cachedStream.SetLength(0);
_outputStream.Flush();
}
// Write is called on the first, third, and so on, page request.
public override void Write(byte[] buffer, int offset, int count)
{
// Cache the content.
_cachedStream.Write(buffer, 0, count);
}
public override void Close()
{
_outputStream.Close();
}
}
// Example usage in a custom HTTP Module on the BeginRequest event.
FilterBase transformFilter = new MapServiceJsonResponseFilter();
response.Filter = new ResponseFilter(response.Filter, transformFilter);
Run Code Online (Sandbox Code Playgroud)
参考文献:
感谢来自周杰伦关于冲洗小费通过执行仅如果过滤器关闭过滤逻辑需要的和尚未闭合被称为增量写我已经能够使过滤器的工作.这可确保在Stream关闭时,Filter仅刷新一次.我用几个简单的字段_isClosing和_isClosed完成了这个,如下面的最终代码所示.
public class ResponseFilter : MemoryStream
{
private readonly Stream _outputStream;
private MemoryStream _cachedStream = new MemoryStream(1024);
private readonly FilterBase _filter;
private bool _isClosing;
private bool _isClosed;
public ResponseFilter (Stream outputStream, FilterBase filter)
{
_outputStream = outputStream;
_filter = filter;
}
public override void Flush()
{
if (_isClosing && !_isClosed)
{
Encoding encoding = HttpContext.Current.Response.ContentEncoding;
string cachedContent = encoding.GetString(_cachedStream.ToArray());
// Filter the cached content
cachedContent = _filter.Filter(cachedContent);
byte[] buffer = encoding.GetBytes(cachedContent);
_cachedStream = new MemoryStream();
_cachedStream.Write(buffer, 0, buffer.Length);
// Write new content to stream
_outputStream.Write(_cachedStream.ToArray(), 0, (int)_cachedStream.Length);
_cachedStream.SetLength(0);
_outputStream.Flush();
}
}
public override void Write(byte[] buffer, int offset, int count)
{
_cachedStream.Write(buffer, 0, count);
}
public override void Close()
{
_isClosing = true;
Flush();
_isClosed = true;
_isClosing = false;
_outputStream.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
我还没有找到上述其他问题的答案,所以我不会在此时将此答案标记为例外.
| 归档时间: |
|
| 查看次数: |
5595 次 |
| 最近记录: |