How to use response compression in ASP.NET Core

Take advantage of response compression middleware in ASP.NET Core to reduce bandwidth requirements and improve the responsiveness of your apps.

car speedometer
Thinkstock

As a thoroughly modern web framework, ASP.NET Core has built-in support for response compression, allowing you to reduce the size of responses and shorten response times. In this article we will examine how response compression works and how we can take advantage of response compression middleware in ASP.NET Core.

Compression is an easy way to reduce network traffic and increase the speed of communication between web server resources and clients or consumers. The popular algorithms available to achieve this compression include Brotli, Gzip, and Deflate, and most modern-day web browsers support response compression. ASP.NET Core’s response compression middleware uses Brotli or Gzip compression by default, depending on which is supported by the client. 

We will implement response compression here using middleware. Note that, if your ASP.NET Core application is being deployed on an IIS, Apache, or Nginx web server, you should instead use the built-in compression provided by the web server, for better performance. Use the response compression middleware only if you’re unable to use the web server’s compression, or if your app is being hosted on a web server that lacks built-in compression, such as Kestrel.

Note that the application pipeline in ASP.NET Core contains a series of request delegates that are invoked sequentially. We will take advantage of one of these middleware components to implement request compression. The middleware pipeline is configured in the Program.cs file. This is where you can chain together your ASP.NET Core pipeline. We will discuss this further in the sections that follow.

Create an ASP.NET Core minimal Web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core 7 minimal Web API project in Visual Studio 2022. Follow these steps:

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, select “NET 7.0 (Current)” as the framework and uncheck the check box that says “Use controllers…” We’ll be using minimal APIs in this example. Leave the “Authentication Type” set to “None” (default).
  9. Ensure that the check boxes “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are all unchecked. We won’t be using any of those features here.
  10. Click Create.

Next, install Microsoft’s ResponseCompression package via the NuGet Package Manager in the ASP.NET Core minimal Web API project you just created. As of this writing, the latest stable version of the ResponseCompression package is 2.2.0. 

> Install-Package Microsoft.AspNetCore.ResponseCompression -Version 2.2.0

We’ll use this ASP.NET Core 7 minimal Web API project to implement response compression in the sections below.

Configure response compression in ASP.NET Core

You can enable response compression in the Program.cs file using the following code.

builder.Services.AddResponseCompression();

The above code snippet will add response compression services to the container. If you want to enable response compression for HTTPS, you should enter the following piece of code in the Program.cs file:

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

To add the response compression middleware to the request processing pipeline, in order to compress responses dynamically, you should configure the HTTP request pipeline using the following piece of code.

app.UseResponseCompression();

Configure compression providers for optimal performance

Note that once you’ve added a compression provider, no other compression provider will be added automatically. You will need to write your own code to add them as needed.

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

You can configure the Brotli and Gzip compression providers for optimal performance (meaning faster compression, but bigger payload) as shown in the code snippet given below.

builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
});
builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Optimal;
});

The complete source code of the Program.cs file

Here’s the complete source code of the Program.cs file for your reference.

using Microsoft.AspNetCore.ResponseCompression;
using System.IO.Compression;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});
builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
});
builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Optimal;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseResponseCompression();
app.MapGet("/", () => "Hello World!");
app.Run();

Create a custom compression provider in ASP.NET Core

You can also create your own compression and decompression providers in ASP.NET Core minimal APIs.

To create a custom compression provider, first create a class that implements the ICompressionProvider interface as shown below.

public class CustomCompressionProvider : ICompressionProvider
{
    public Stream CreateStream(Stream outputStream)
    {
        // Write your code here to compress
        return outputStream;
    }
}

Next register and configure the custom compression provider in the Program.cs using the code given below.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCompression(options =>
{
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
});
var app = builder.Build();
app.UseResponseCompression();
app.MapGet("/", () => "Hello World!");
app.Run();

Implement a controller in ASP.NET Core

Now that response compression has been installed in the project and configured, let’s implement a controller to demonstrate response compression. To do this, select the Controllers solution folder of your project and then click Add -> Controller. Select the “API Controller - Empty” template from the list of templates displayed in the Add Scaffold window and enter a name for the controller when prompted. Then replace the default code with the following.

[Produces("application/json")]
    [Route("api/Default")]
    public class DefaultController : Controller
    {
        // GET: api/Default
        [HttpGet]
        public List<Message> Get()
        {
            List<Message> lst = new List<Message>();
            for(int index=0; index <100; index++)
            {
                Message message = new Message();
                message.Text = “This is a text message.”;
                lst.Add(message);
            }
            return lst;
        }
    }

The Message class contains just one string property.

public class Message
    {
        public string Text { get; set; }
    }

When I executed this controller method, I could see that the size of the compressed response was 0.091 KB. When compression was disabled, the size of the response was 3.419 KB. To disable response compression, you can simply comment out the appropriate lines in the Program.cs file.

//builder.Services.AddResponseCompression();
//app.UseResponseCompression();

For response compression to work, the client must inform the server of its capabilities by sending the Accept-Encoding header with the request. The server in turn should include this header with compressed response to inform the client that the response has been compressed.

Note that while response compression in ASP.NET Core is flexible, easy to configure, and easy to use, it is slower than IIS compression. You’ll want to rely on the compression provided by IIS and other web servers whenever you can. You can learn more about response compression in ASP.NET Core from Microsoft’s ASP.NET Core documentation.

Using HTTPS compression

Note that compression over HTTPS could expose sensitive data to CRIME and BREACH attacks. An attacker could intercept HTTPS compression traffic to steal credentials or session cookies, compromising the security of the application. You can prevent such attacks by configuring the web server to utilize TLS instead of HTTPS compression.

TLS compression compresses data at a higher layer than HTTPS, making it harder for attackers to exploit. Unlike traditional compression techniques that compress content at the application layer, TLS compression compresses data at the transport layer.

Copyright © 2023 IDG Communications, Inc.