HttpResponse 过滤器不返回任何内容
我编写了一个 HttpModule,用于拦截对 WebResource.axd 处理程序的调用,以便我可以对 javascript 执行一些后处理。
该模块包装 Response.Filter 流以执行其处理并将其更改写入底层流。
我遇到的问题是脚本没有返回到浏览器。
因此,作为一个非常简单的示例,仅充当传递,模块如下所示:
public class ResourceModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
}
void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication context = sender as HttpApplication;
if (context.Request.Url.ToString().Contains("WebResource.axd"))
{
context.Response.Filter = new ResourceFilter(context.Response.Filter);
}
}
}
并且仅输出接收到的内容的 ResourceFilter 如下所示:
public class ResourceFilter : MemoryStream
{
private Stream inner;
public ResourceFilter(Stream inner)
{
this.inner = inner;
}
public override void Write(byte[] buffer, int offset, int count)
{
inner.Write(buffer, offset, count);
}
}
我可以附加并查看正在调用的模块和过滤器,但是当我浏览到WebResource.axd url 我什么也没得到。
我已经使用此模式来实现在 aspx 页面上执行处理的模块,并且它们工作得很好。看来与 WebResource.axd 的交互存在一些问题,阻止了此工作。
I have written a HttpModule that I am using to intercept calls the the WebResource.axd handler so I can perform some post processing on the javascript.
The module wraps the Response.Filter stream to perform its processing and writes it's changes to the underlying stream.
The problem I have is that the script does not get returned to the browser.
So as a really simple example that just acts as a pass through, the module looks like this:
public class ResourceModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
}
void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication context = sender as HttpApplication;
if (context.Request.Url.ToString().Contains("WebResource.axd"))
{
context.Response.Filter = new ResourceFilter(context.Response.Filter);
}
}
}
and the ResourceFilter that just outputs what it receives looks like this:
public class ResourceFilter : MemoryStream
{
private Stream inner;
public ResourceFilter(Stream inner)
{
this.inner = inner;
}
public override void Write(byte[] buffer, int offset, int count)
{
inner.Write(buffer, offset, count);
}
}
I can attach and see the module and filter being invoked, but when I browse to WebResource.axd url I get nothing back.
I have used this pattern to implement modules that perform processing on aspx pages and they work just fine. It appears there is something about the interaction with the WebResource.axd that prevents this working.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我做了一个小项目并准确地重现了您的问题。我正在运行 fiddler 来仔细查看响应(包括标头),发现仅在 *.axd 文件的过滤器上发生了这种情况。
经过一番搜索后,我发现 这个< /a> Daniel Richardson 的文章,他也有同样的问题。
事实证明,
System.Web.Handlers.AssemblyResourceLoader
(axds 经过的)设置了一个标志来忽略进一步的写入。Daniel 给出了一个使用反射来取消设置此标志并允许您的过滤器处理 axd 结果的示例。我尝试了一下,效果很好。不过,最好记住这对性能的影响,正如 Daniel 所说,ASP.NET 实现可能会发生变化。
I made a small project and recreated your problem exactly. I was running fiddler to have a good look at the response, including headers and found it was only on filters on *.axd files where this happened.
After some searching I found this article by Daniel Richardson who had the same issue.
Turns out that the
System.Web.Handlers.AssemblyResourceLoader
(which axds go through) sets a flag to ignore further writes.Daniel gives an example of using reflection to unset this flag and allow your filter to work on the result of the axd. I tried it out and it works well. Best keep in mind any performance impact of this though, and as Daniel says, the ASP.NET implementations could change.
根据我的经验,过滤器最迟需要在 PreRequestHandlerExecute 事件中“挂钩”,才能使其在早于版本 7 的 IIS 版本中工作。
Based on my experience the Filter needs to be 'hooked' in the PreRequestHandlerExecute event at the latest to make it work in IIS version older than version 7.