views:

756

answers:

2

I'm not sure if this is an ASP.NET MVC specific thing or ASP.NET in general but here's what's happening. I have an action filter that removes whitespace by the use of a response filter:

public class StripWhitespaceAttribute : ActionFilterAttribute
{
 public StripWhitespaceAttribute ()
 {

 }

 public override void OnResultExecuted(ResultExecutedContext filterContext)
 {
  base.OnResultExecuted(filterContext);

  filterContext.HttpContext.Response.Filter = new WhitespaceFilter(filterContext.HttpContext.Response.Filter);
 }
}

When used in conjunction with the OutputCache attribute, my calls to Response.WriteSubstitution for "donut hole caching" do not work. The first and second time the page loads the callback passed to WriteSubstitution get called, after that they are not called anymore until the output cache expires. I've noticed this with not just this particular filter but any filter used on Response.Filter... am I missing something?

I also forgot to mention I've tried this without the use of an MVC action filter attribute by attaching to the PostReleaseRequestState event in the global.asax and setting the Response.Filter value there... but still no luck.

+2  A: 

AFAIK, the problem is that the action filters doesn't get executed if the request goes to the output cache. The AuthorizeAttribute works around this problem by calling some obscure Output Cache API. However, I don't think that is the best solution for what you're are trying to do.

You should be working with output cache, not around it. What you should be doing instead is making sure that the spaces are removed from the response before it gets stored in the output cache.

Update

It seems that attaching a filter, no matter what filter, disables the WriteSubstitution functionality as you suspect. I've tried following the trail in the HttpResponse class using reflector but I can't find any proof that confirms this suspicion. I think the answer lies within the HttpWriter class.

Another Update

It so happens that I'm currently reading the excellent book "Pro ASP.NET MVC Framework" by Steve Sanderson (buy it if you don't already have it). In chapter 10 he links to a post on his blog where he talks about partial output caching and the poor integration between the MVC framework and the output cache. I haven't tried the custom outputcache attribute in the post yet... I will try it out and let you know if it does anything to solve the problem.

JohannesH
Yes, that's the same conclusion I came up with too... I went through the code with reflector and couldn't find anything that would disable the call to WriteSubstitution... Let me know if you find anything else but I think for now I just have to disable the filter...
Shane Andrade
+2  A: 

This KB article may offer some insight into the root cause of this issue. While the filter 'breaks' caching in IIS6 it throws an error in IIS 7. This seems to be a design / test-time improvement at best.

UPDATE

Here's an official "answer" from MS Dev Support on this issue.

Question:
What is the alternative to response filtering in ASP.NET for modifying HTML rendered by another process when:
1. The other process cannot be modified
2. Post-cache substitution must be supported

Answer:
"Yes, you question is clear as blue sky and this is officially claimed to be not support. As Post-cache substitution would combine certain substitution chunks to the response bytes while response filtering expects to filter the raw bytes of the response(not modified). So the previously combined substitution chunks cannot be preserved anymore.

There is not an alternative from Microsoft so far."

Jason Weber