Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

middleware - Headers already sent in .net 5

We have middleware in a web API, which we use to filter the resposne body from a controller After updating our service to .net 5, replacing the output fails with

System.InvalidOperationException: Headers already sent.
         at Microsoft.AspNetCore.Server.HttpSys.Response.CheckResponseStarted()
         at Microsoft.AspNetCore.Server.HttpSys.FeatureContext.ConsiderEnablingResponseCache()
         at Microsoft.AspNetCore.Server.HttpSys.FeatureContext.OnResponseStart()
         at Microsoft.AspNetCore.Server.HttpSys.FeatureContext.CompleteAsync()
         at Microsoft.AspNetCore.Server.HttpSys.RequestContext.Execute()
         at Microsoft.AspNetCore.Server.HttpSys.RequestContext.Execute()

Our middleware to filter the output looks something like this

internal class FilterOutput : IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var originalBodyStream = context.Response.Body;
        var tempResponseBody = new MemoryStream();
        context.Response.Body = tempResponseBody;
        context.Response.OnStarting(async state =>
        {
            await FilterResponse(context, tempResponseBody, originalBodyStream);
        }, context);
        await next(context);
    }

    private async Task FilterResponse(HttpContext context, MemoryStream tempResponseBody, Stream originalBodyStream)
    {
        if (context.Response.StatusCode == 200)
        {
            var output = Encoding.UTF8.GetString(tempResponseBody.GetBuffer());
            var newOutput = output.Filter(null);

            var updatedStream = GenerateStreamFromString(newOutput);
            await updatedStream.CopyToAsync(originalBodyStream);
            context.Response.Body = originalBodyStream;
            return;
        }
        await tempResponseBody.CopyToAsync(originalBodyStream);
    }

    public static Stream GenerateStreamFromString(string s)
    {
        var stream = new MemoryStream();
        var writer = new StreamWriter(stream);
        writer.Write(s);
        writer.Flush();
        stream.Position = 0;
        return stream;
    }
}

I realize net 5 is propably more asynchronous and sends headers earlier Is there a way to stop that, so I can modify the output body in middleware?

question from:https://stackoverflow.com/questions/65919709/headers-already-sent-in-net-5

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...