Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC - Response.Filter is null when using ActionFilterAttribute in RegisterGlobalFilters()

I want to use G-ZIP on my website, I googled the following code:

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var acceptEncoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
        if (!string.IsNullOrEmpty(acceptEncoding))
        {
            acceptEncoding = acceptEncoding.ToLower();
            var 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);
            }
        }
    }
}

It works fine when I set the attribute to a Controller or an Action.

[Compress]
public class PostController : Controller

I don't want to manully do this on every piece of code, so I registered this attribute in

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new CompressAttribute());
}

But when I run the application, exception came on this line of code:

response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);

the response.Filter is null.

I want to know why this is happening and how to solve this. Thanks!

- Update:

I found that the exception happens only when the controller contains a child action, and it's being invoked.

like image 260
Edi Wang Avatar asked Feb 25 '13 12:02

Edi Wang


People also ask

How do I redirect an action filter?

Alternatively to a redirect, if it is calling your own code, you could use this: actionContext. Result = new RedirectToRouteResult( new RouteValueDictionary(new { controller = "Home", action = "Error" }) ); actionContext.

What is the use of a filter in ASP.NET Core application?

Filters in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline. Built-in filters handle tasks such as: Authorization, preventing access to resources a user isn't authorized for. Response caching, short-circuiting the request pipeline to return a cached response.

How do I register a global filter?

ASP.NET MVC 3.0 introduces global action filters - an easy way to apply an action filter to every action in an MVC application. All you need to do is register the filters during application startup: protected void Application_Start() { ... GlobalFilters.


1 Answers

My solution was to filter all child action.

if (filterContext.IsChildAction) return;

Use this code on the top of your method.

public class CompressAttribute : ActionFilterAttribute
{    
   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       if (filterContext.IsChildAction) return;

       ...
    }
}
like image 60
Tomasz Maj Avatar answered Oct 05 '22 08:10

Tomasz Maj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!