ASP.NET - ASP.NET Core Request Decompression
ASP.NET Core Request Decompression is a feature that allows an application to receive HTTP requests whose request bodies have been compressed before being sent to the server. Instead of requiring every endpoint to manually detect compressed data and decompress it, ASP.NET Core provides request decompression middleware that can perform this operation automatically. This is particularly useful for APIs that receive large JSON documents, XML payloads, or other data where compression can significantly reduce the amount of data transferred over a network.
What Is Request Decompression?
When a client sends data to an ASP.NET Core application, the request normally contains a body. For example, an API might receive a JSON document through a POST request.
Without compression, the request might look conceptually like this:
Client
|
| Uncompressed JSON data
v
ASP.NET Core API
When request compression is used, the client compresses the request body before transmission:
Client
|
| Compressed request body
v
ASP.NET Core Request Decompression
|
| Decompressed request body
v
API Endpoint
The server can therefore receive a smaller amount of data over the network and decompress it before the application processes the request.
ASP.NET Core determines whether a request body is compressed by examining the Content-Encoding HTTP header. If the header corresponds to a supported decompression provider, the middleware creates an appropriate decompression stream around HttpRequest.Body.
Why Request Decompression Is Useful
The primary advantage is reduced network traffic.
Consider an API that receives a large JSON document containing thousands of records. Sending the document without compression could require several megabytes of network bandwidth. Compression can considerably reduce the size of the transmitted request.
This can be beneficial when:
-
APIs receive large JSON or XML documents.
-
Clients operate over slower networks.
-
Applications process large data imports.
-
Mobile or remote clients need to minimize bandwidth usage.
-
Services communicate with one another over networks where reducing payload size is important.
However, compression does not make the underlying data smaller permanently. The client sends compressed data, and the server expands it before the application processes it.
How Content-Encoding Works
The Content-Encoding HTTP header tells the server how the request body has been encoded.
For example:
POST /api/orders HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Encoding: gzip
The Content-Encoding: gzip value tells ASP.NET Core that the request body is compressed using Gzip.
ASP.NET Core's request decompression middleware supports standard encodings through decompression providers. The current Microsoft documentation lists Brotli (br), Deflate (deflate), Gzip (gzip), and, in the current .NET 10 documentation, Zstandard (zstd).
Request Decompression Middleware
ASP.NET Core provides request decompression middleware specifically for this purpose.
A basic configuration is:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRequestDecompression();
var app = builder.Build();
app.UseRequestDecompression();
app.MapPost("/", (HttpRequest request) =>
{
return Results.Stream(request.Body);
});
app.Run();
There are two important parts of this configuration.
First, AddRequestDecompression() registers the required services.
builder.Services.AddRequestDecompression();
Second, UseRequestDecompression() adds the middleware to the application's HTTP request pipeline.
app.UseRequestDecompression();
Once configured, ASP.NET Core can automatically process supported compressed request bodies rather than requiring individual endpoints to implement decompression logic.
How the Processing Works
The process can be understood in several stages.
Stage 1: Client Compresses the Data
The client prepares the request body and compresses it using an encoding such as Gzip or Brotli.
Stage 2: Client Sends the Request
The client sends the compressed body along with the appropriate Content-Encoding header.
For example:
Content-Encoding: gzip
Stage 3: Middleware Examines the Header
The request decompression middleware checks the Content-Encoding value.
If a matching decompression provider exists, ASP.NET Core knows how to process the request.
Stage 4: Request Body Is Wrapped
ASP.NET Core wraps HttpRequest.Body with an appropriate decompression stream.
This means the endpoint can read the request body as decompressed data without having to manually perform the decompression.
Stage 5: Application Reads the Data
When the endpoint or model-binding system reads the request body, decompression occurs.
An important detail is that ASP.NET Core does not eagerly decompress the entire request immediately when it arrives. Decompression occurs as the request body is read.
Request Decompression and Model Binding
Request decompression works naturally with ASP.NET Core's request-processing pipeline.
For example, an API might receive a model:
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
An endpoint could receive the model:
app.MapPost("/products", (Product product) =>
{
return Results.Ok(product);
});
If the incoming request body is compressed and the appropriate decompression middleware is enabled, the compressed body can be decompressed before the application consumes the request data.
This allows application developers to focus on processing the Product rather than implementing compression-specific logic inside the endpoint.
Handling Unsupported Encodings
Not every possible Content-Encoding value is automatically supported.
If a request contains an encoding for which the application has no matching decompression provider, the middleware cannot decompress that content. In such cases, the request continues through the pipeline rather than being automatically decompressed. Microsoft also notes that requests containing multiple Content-Encoding values are passed onward when the middleware cannot process them.
Therefore, applications that depend on compressed requests should ensure that the client and server agree on the supported encoding.
Custom Decompression Providers
ASP.NET Core also allows developers to add support for custom compression formats.
A custom provider can implement IDecompressionProvider.
For example:
public class CustomDecompressionProvider : IDecompressionProvider
{
public Stream GetDecompressionStream(Stream stream)
{
// Custom decompression logic
return stream;
}
}
The provider can then be registered with the request decompression configuration:
builder.Services.AddRequestDecompression(options =>
{
options.DecompressionProviders.Add(
"custom",
new CustomDecompressionProvider());
});
The application can consequently recognize the corresponding Content-Encoding value and use the custom provider to process the request.
This is useful when an organization uses a specialized compression format that is not included among the default providers.
Request Size Limits
One of the most important aspects of request decompression is controlling the size of the decompressed data.
A compressed request can be relatively small while expanding into a much larger amount of data. This creates a potential resource-consumption problem.
For example:
Compressed request: 5 MB
|
v
Decompression
|
v
Decompressed request: 500 MB
Allowing unrestricted expansion could consume excessive memory, CPU, or other server resources.
ASP.NET Core therefore applies request body size limits to the decompressed request. If the amount of decompressed data read exceeds the applicable limit, ASP.NET Core prevents additional data from being read and can throw an InvalidOperationException.
Decompression Bombs
A particularly important security concern is a decompression bomb.
A maliciously constructed compressed payload can have a relatively small compressed size but expand dramatically when decompressed.
For example:
Small malicious payload
|
v
Decompression
|
v
Extremely large data
|
v
Excessive server resources
This can potentially contribute to denial-of-service conditions.
For this reason, developers should not simply remove request-size limits without considering the security implications. Microsoft specifically warns that disabling request body limits can create risks associated with uncontrolled resource consumption and denial-of-service attacks.
Request Size Configuration
ASP.NET Core allows request size limits to be controlled at different levels.
For MVC endpoints, request-size metadata can be specified through mechanisms such as RequestSizeLimitAttribute.
At the server level, the maximum request body size can also be controlled through the web server configuration.
For example, applications hosted on Kestrel can use:
KestrelServerLimits.MaxRequestBodySize
Applications hosted through IIS or HTTP.sys have their respective server-level configuration options.
The correct limit depends on the application's requirements. An API designed to receive small JSON requests should generally use a much smaller limit than a service designed to receive large data-import files.
Request Decompression vs Response Compression
Request decompression and response compression are related but perform opposite operations.
Request Decompression
The client compresses the request:
Client
|
| Compressed data
v
Server
|
| Decompress
v
Application
Response Compression
The server compresses the response:
Application
|
| Response data
v
Server
|
| Compress
v
Client
ASP.NET Core provides separate functionality for response compression. Response compression uses headers such as Accept-Encoding and Content-Encoding to negotiate and communicate supported compression formats.
Therefore, enabling response compression does not automatically mean that the application can accept compressed request bodies. Request decompression needs to be configured separately.
Advantages of Request Decompression
Request decompression provides several practical advantages.
Reduced Network Usage
Compressed requests require fewer bytes to travel between the client and server.
Better Performance for Large Payloads
For suitable data types, smaller network payloads can reduce transmission time.
Less Application Code
Developers do not need to implement decompression logic separately inside every API endpoint.
Centralized Configuration
Decompression can be configured as part of the ASP.NET Core request pipeline.
Support for Multiple Encodings
The built-in providers allow applications to work with several established compression formats.
Limitations and Considerations
Request decompression is not automatically beneficial for every request.
Compression requires processing on both sides. The client must compress the data, while the server must decompress it.
Highly compressed data can therefore involve additional CPU processing.
There is also little benefit in compressing data that is already highly compressed. For example, certain media and archive formats may not become significantly smaller through another compression layer.
Developers should therefore consider:
-
Request size.
-
Data type.
-
Network bandwidth.
-
CPU availability.
-
Compression and decompression time.
-
Security limits.
-
Client compatibility.
Example Request Flow
A complete example can be represented as follows:
Client Application
|
| JSON data
v
Compression
|
| gzip encoded data
v
HTTP Request
Content-Encoding: gzip
|
v
ASP.NET Core
|
v
Request Decompression Middleware
|
v
Decompressed Request Body
|
v
Model Binding / Endpoint
|
v
Application Logic
This architecture separates the transport concern from the application logic. The endpoint can work with the decompressed request data without needing to know the details of how the client compressed it.
Best Practices
When implementing request decompression in ASP.NET Core, developers should follow several practices.
First, enable decompression only when the application actually needs to accept compressed request bodies.
Second, use established compression formats supported by the clients communicating with the application.
Third, maintain reasonable request-size limits. These limits are particularly important because the decompressed content can be considerably larger than the transmitted content.
Fourth, test malformed compressed data. ASP.NET Core can throw exceptions when compressed content is invalid, so applications should ensure that their error-handling strategy appropriately handles such situations.
Finally, do not disable request-size protection without carefully evaluating the possibility of resource-exhaustion or denial-of-service attacks.
Conclusion
ASP.NET Core Request Decompression provides a standardized way for web applications and APIs to accept compressed HTTP request bodies. The middleware examines the Content-Encoding header, selects an appropriate decompression provider, and exposes the decompressed request body to the application. Current ASP.NET Core documentation supports common formats such as Brotli, Deflate, Gzip, and Zstandard in the .NET 10 documentation.
The feature is especially useful for APIs that receive large amounts of structured data because compression can reduce network traffic before the request reaches the server. However, developers must pay particular attention to decompressed request-size limits and security because a small compressed payload can expand into a very large amount of data. Properly configured request decompression can therefore improve network efficiency while keeping the application architecture clean and manageable.