views:

303

answers:

1

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.

A: 

Hi Steve

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.