I am trying to get [CompressFilter] working with donut caching and running into issues.
What happens is that the whole page gets cached and not just the donut. The source for the CompressFilter
I am using is below. I changed this from the original source to use OnResultExecuted
instead of OnActionExecuting()
because I needed access to the type of the result to avoid caching certain ActionResult subclasses.
Looking at the actual MVC v1 source code for OutputCacheAttribute
it looks like it also is using OnResultExecuted()
, but I dont think that fact directly is causing the conflict.
I don't know enough about how substitution caching works to understand quite why it behaves the way it does. I think it is notable to say though that this does not end up with any kind of corrupted display. It just behaves like there is no donut!
Its looking like I will have to use some kind of IIs 'plug-in' to handle caching, which I really wanted to avoid having to do, but its looking like I need donut caching too.
I'm actually more interested right now to know why it has this effect, but a solution if possible would be great too.
public class CompressFilter : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
HttpRequestBase request = filterContext.HttpContext.Request;
// dont encode images!
if (filterContext.Result is ImageResult)
{
return;
}
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding)) return;
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponseBase response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("GZIP"))
{
response.AppendHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("DEFLATE"))
{
response.AppendHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
}