web-dev-qa-db-fra.com

Désactiver la segmentation dans Asp.Net Core

J'utilise une application Web Azure Asp.Net Core pour fournir une API RESTful à un client, et le client ne gère pas correctement la segmentation.

Est-il possible de désactiver complètement Transfer-Encoding: chunked soit au niveau du contrôleur, soit dans web.config?

EDIT: je retourne un JsonResult un peu comme ceci:

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

    return Json( AuthResultData );
}
17
Iain Brown

Cela m'a pris toute la journée, mais j'ai finalement compris comment se débarrasser des segments dans .Net Core 2.2

L'astuce consiste à lire le corps de réponse dans votre propre MemoryStream afin que vous puissiez obtenir la longueur. Une fois que vous avez fait cela, vous pouvez définir l'en-tête de la longueur du contenu et IIS ne le fragmentera pas. Je suppose que cela fonctionnerait également pour Azure, mais je ne l'ai pas testé.

Voici le middleware:

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);
        }
    }
}

Ajoutez ensuite ceci dans Démarrage:

app.UseMiddleware<DeChunkerMiddleware>();

Il doit être avant app.UseMvC().

8
Pharylon

Il fonctionne dans .NET Core 2.0. Définissez simplement ContentLength avant d'écrire les résultats dans le flux du corps de la réponse.

Classe de démarrage 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

Dans ASP.NET core, cela semble fonctionner sur plusieurs hôtes:

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

Indique la fonction d'identité (c'est-à-dire pas de compression ni de modification). Ce jeton, sauf indication contraire explicite, est toujours considéré comme acceptable.

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

Cela fonctionne également lorsque vous désactivez explicitement la mise en mémoire tampon des réponses:

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