how to compress the output send by an asp.net mvc application??
-
Why not just set `
` or even ` ` in `web.comfig` http://www.iis.net/configreference/system.webserver/httpcompression http://stackoverflow.com/questions/9235337/gzipping-content-files-in-asp-net-mvc-3? – angularrocks.com Dec 30 '13 at 00:56 -
You can also increase the performance by using compression and caching for the response data. Have a look at the following link :- http://weblogs.asp.net/rashid/asp-net-mvc-action-filter-caching-and-compression – Aishwarya Nagar Feb 09 '16 at 07:35
3 Answers
Here's what i use (as of this monent in time):
using System.IO.Compression;
public class CompressAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var encodingsAccepted = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(encodingsAccepted)) return;
encodingsAccepted = encodingsAccepted.ToLowerInvariant();
var response = filterContext.HttpContext.Response;
if (encodingsAccepted.Contains("deflate"))
{
response.AppendHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
else if (encodingsAccepted.Contains("gzip"))
{
response.AppendHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
}
}
usage in controller:
[Compress]
public class BookingController : BaseController
{...}
there are other varients, but this works quite well. (btw, i use the [Compress] attribute on my BaseController to save duplication across the project, whereas the above is doing it on a controller by controller basis.
[Edit] as mentioned in the para above. to simplify usage, you can also include [Compress]
oneshot in the BaseController itself, thereby, every inherited child controller accesses the functionality by default:
[Compress]
public class BaseController : Controller
{...}

- 47,252
- 12
- 78
- 118

- 22,305
- 4
- 49
- 63
-
actually, looked at your example - very similar indeed - spooky :). i've been using this code for over a year, so can verify that it works very well ... – jim tollan Sep 27 '10 at 09:31
-
is is possible i can do some settings in web.config to do the compression. one more thing i want to know, how to check howmuch overhead is added to server by compression code we are running here. – Praveen Prasad Sep 27 '10 at 11:51
-
praveen- unfortunately, a web.config solution isn't one that i'm aware of (i also think it would be too course grained to be flexible). as for memory usage, i think you may have to use some tool outside of IIS to measure that. – jim tollan Sep 27 '10 at 14:35
-
-
Hi mark - it's actually as simple as just moving the `[Compress]` attribute down from the child controller to decorate the `BaseController` instead. I've added an amendment to show this – jim tollan May 17 '13 at 16:27
-
@jimtollan And then have every controller derive from your BaseController? Does this work for CSS and Javascript files? or just dynamic content? – Mark May 17 '13 at 16:36
-
Hi mark, yes, every controller that derives from BaseController will inherit this logic. this works for any content that can be gzipped, tho of course, some css and images etc may by default be pulled from local cache anyway. – jim tollan May 18 '13 at 12:42
-
Why not just use IIS `urlCompression` ? http://stackoverflow.com/questions/9235337/gzipping-content-files-in-asp-net-mvc-3?lq=1 – angularrocks.com Dec 30 '13 at 00:55
-
hey there, good point, tho the above, as mentioned in my answer (and actually also mentioned in the comments above re *web.config being too course grained!!*), gives an alternative for those who prefer to be able to roll in compression at a fine grained, individual controller level on a needs must basis (rather than across the board, which may not be desirable for the use case). :). happy new year when the hour approaches, wherever you are. hoots mon the noo... – jim tollan Dec 30 '13 at 11:44
-
9I added it as a global filter, in my startup class I added `GlobalFilter.Filters.Add(new CompressionAttribute());` and it works #1! Also inverted the `if` clause to make sure `gzip` is used instead of `deflate` when both encodings are supported. – Charles Ouellet Jan 14 '15 at 18:52
-
2Just wanted to add, that in case you didn't start by deriving from a base controller, don't be scared. You can always use an IoC container that will handle that. For example, in Ninject (MVC 5) you can use: "kernel.BindFilter
(FilterScope.Controller, 0);" under the "RegisterServices(IKernel kernel)" method! – Jose A Oct 03 '15 at 17:46 -
Jose, so glad that this little Attribute approach is still working, 5 years later and 4 versions of MVC... I just love this tech for that reason, build and consolidate!! – jim tollan Oct 03 '15 at 20:05
-
1Great answer. But why you put `deflate` option first, I change order so `gzip` is first and now give around 10% more compresion – Juan Carlos Oropeza Sep 09 '16 at 13:49
-
The one issue IU had with this solution is that it doesn't honour the order of the accept-encoding header. If you receive gzip, deflate the priority is GZIP? – Ed Broome Nov 14 '17 at 10:48
-
Thanks for a nice solution! I just ran into the problem that response.Filter is null - see this question for the solution to that: https://stackoverflow.com/questions/15067049/asp-net-mvc-response-filter-is-null-when-using-actionfilterattribute-in-regist – ylva May 16 '18 at 08:54
-
1Important! You should check response.Filter for null before putting it in stream! I encountered issue, when locally everything is OK, but when deployed to Azure service it fails. – Yehor Androsov Jan 11 '19 at 17:42
Have a look at this article which outlines a nifty method utilizing Action Filters.
For example:
[CompressFilter]
public void Category(string name, int? page)
And as an added bonus, it also includes a CacheFilter.

- 239,200
- 50
- 490
- 574

- 8,940
- 2
- 34
- 43
-
okie, testing this, one more thing i want to know , how can i check whether the data iam getting from server is gzipped or not?? – Praveen Prasad Sep 27 '10 at 09:13
-
-
1Not working on MVC5, IIS 8.5 and .Net 4.5, any help will be appreciated. – aadi1295 Jul 21 '15 at 12:34
For .NET Core 2.1 there is a new package that can be used ( Microsoft.AspNetCore.ResponseCompression )
Simple sample to get going, after installing the package:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.AddResponseCompression(options =>
{
options.Providers.Add<GzipCompressionProvider>();
options.EnableForHttps = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
}
}
You can read more about it here: https://learn.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-2.1&tabs=aspnetcore2x

- 5,543
- 6
- 44
- 60