web-dev-qa-db-ja.com

Asp.Net Coreでチャンクを無効にする

Asp.Net Core Azure Webアプリを使用してクライアントにRESTful APIを提供していますが、クライアントはチャンクを正しく処理しません。

コントローラレベルまたはweb.configでTransfer-Encoding: chunkedを完全にオフにすることは可能ですか?

編集:私は次のようなJsonResultを返しています:

[HttpPost]
[Produces( "application/json" )]
public IActionResult Post( [FromBody] AuthRequest RequestData )
{
    AuthResult AuthResultData = new AuthResult();

    return Json( AuthResultData );
}
17
Iain Brown

これには1日かかりましたが、最終的に.Net Core 2.2でチャンクを取り除く方法を見つけました

コツは、レスポンスボディを独自のMemoryStreamに読み込んで、長さを取得することです。これを行ったら、content-lengthヘッダーを設定できます。IISはチャンクしません。これはAzureでも機能すると思いますが、テストしていません。

ここにミドルウェアがあります:

_public class DeChunkerMiddleware
{
    private readonly RequestDelegate _next;

    public DeChunkerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var originalBodyStream = context.Response.Body;
        using (var responseBody = new MemoryStream())
        {
            context.Response.Body = responseBody;
            long length = 0;
            context.Response.OnStarting(() =>
            {
                context.Response.Headers.ContentLength = length;
                return Task.CompletedTask;
            });
            await _next(context);
            //if you want to read the body, uncomment these lines.
            //context.Response.Body.Seek(0, SeekOrigin.Begin);
            //var body = await new StreamReader(context.Response.Body).ReadToEndAsync();
            length = context.Response.Body.Length;
            context.Response.Body.Seek(0, SeekOrigin.Begin);
            await responseBody.CopyToAsync(originalBodyStream);
        }
    }
}
_

次に、これをスタートアップに追加します。

_app.UseMiddleware<DeChunkerMiddleware>();
_

app.UseMvC()の前にある必要があります。

8
Pharylon

.NET Core 2.0で動作します。結果をレスポンスボディストリームに書き込む前にContentLengthを設定するだけです。

Intスタートアップクラス:

app.Use(async (ctx, next) =>
{
    var stream = new xxxResultTranslatorStream(ctx.Response.Body);
    ctx.Response.Body = stream;

    await Run(ctx, next);

    stream.Translate(ctx);
    ctx.Response.Body = stream.Stream;
});

Int xxxResultTranslatorStream:

ctx.Response.Headers.ContentLength=40;
stream.Write(writeTargetByte, 0, writeTargetByte.Length);
2
naz

ASP.NETコアでは、これはホスト間で機能するようです。

response.Headers["Content-Encoding"] = "identity";
response.Headers["Transfer-Encoding"] = "identity";

識別関数を示します(つまり、圧縮も変更もありません)。このトークンは、明示的に指定されている場合を除き、常に受け入れ可能と見なされます。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encodinghttps://developer.mozilla.org/en-US/ docs/Web/HTTP/Headers/Transfer-Encoding

これは、応答バッファリングを明示的に無効にした場合にも機能します。

var bufferingFeature = httpContext.Features.Get<IHttpBufferingFeature>();
bufferingFeature?.DisableResponseBuffering();
2
George Tsiokos