最小 API 中间件处理后不支持的媒体类型 (415)

Minimal API Unsupported media type (415) after processing by middleware

我正在使用 Gzip 中间件,它解压缩 "application/gzip" 请求并将它们更改为 "application/json"。它适用于 .Net 3.1 和 5,但在 .Net 6(最小 API)中我得到状态 415(不支持的媒体类型)响应。中间件保持不变,在一个单独的项目中(.net 标准 2.1)。在调试器中,一开始似乎一切正常,请求一如既往地由中间件处理并进一步传递。我尝试发送一个正常的 json,只更改了 content-type header,但得到了同样的错误。

更新: 我找到了更多中间件代码。我需要使用 "content-type": "application/gzip" 处理请求,因为这是许多与 api.

通信的旧设备发送的格式

Program.cs:

//... Services ...//
#region Middleware
if (app.Environment.IsDevelopment())

{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.All
});

app.UseRouting();
app.UseAuthorization();
app.UseGzipRequestDecompression(); // My custom middleware
app.UseGlobalExceptionHandler();
#endregion //Middleware

中间件:

public async Task InvokeAsync(HttpContext httpContext)
    {
        var request = httpContext.Request;
        if (request.ContentType == "application/gzip")
        {
            
            using (var gzipStream = new GZipStream(request.Body, CompressionMode.Decompress))
            {
                await gzipStream.CopyToAsync(outputStream);
            }

            outputStream.Seek(0, SeekOrigin.Begin);
            
            // Replace request content with the newly decompressed stream
            request.Body = outputStream;
            
            // Change request type to json
            request.ContentType = "application/json";
        }

        await _next(httpContext);
    }

根据@JeremyLakeman的建议,问题出在.UseRouting

根据microsoft documentation

Apps typically don't need to call UseRouting or UseEndpoints. WebApplicationBuilder configures a middleware pipeline that wraps middleware added in Program.cs with UseRouting and UseEndpoints. However, apps can change the order in which UseRouting and UseEndpoints run by calling these methods explicitly.

解决方案是将 .UseRouting 移到中间件之后(而不是删除它),所以它看起来像这样:

app.UseAuthorization();
app.UseGzipRequestDecompression();
app.UseGlobalExceptionHandler();
app.UseRouting();
#endregion //Middleware