ASP.NET Core – reuse request HttpContext

In some case, in controller, we want to capture request’s raw payload and deal with it for example forward to some url like proxy.

In controller, if you do this:

string payload = "";

using (StreamReader stream = new StreamReader(HttpContext.Request.Body))
{
    payload = stream.ReadToEnd();
}

you will get empty payload even if the payload actually not empty.

You are missing one critical step, call Request.EnableRewind(), so before you use HttpContext.Request.Body, call Request.EnableRewind(), and then you can get all raw request data:

Request.EnableRewind();

string payload = "";

using (StreamReader stream = new StreamReader(HttpContext.Request.Body))
{
    payload = stream.ReadToEnd();
}

If you want to enable rewind globally, you can create a middleware and use it in startup.cs as a global config.

Add new file EnableRequestRewindMiddleware.cs

public class EnableRequestRewindMiddleware
{
    private readonly RequestDelegate _next;

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

    public async Task Invoke(HttpContext context)
    {
        context.Request.EnableRewind();
        await _next(context);
    }
}

Add EnableRequestRewindExtension.cs

public static class EnableRequestRewindExtension
{
    public static IApplicationBuilder UseEnableRequestRewind(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<EnableRequestRewindMiddleware>();
    }
}

And modify Configure method in Startup.cs file to use it:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ......
    app.UseEnableRequestRewind();
}

Leave a comment