Search code examples
c#.net.net-6.0webapi

Create a Middleware to Set the Response Time


I create a middleware to stop every request in my WebAPI, but I want to set the Response Time in the Headers.

Example without the middleware:

[HttpGet]
public IActionResult Index()
{
    var watcher = Stopwatch.StartNew();
    watcher.Stop();
    HttpContext.Response.Headers.Add("x-response-time", watcher.ElapsedMilliseconds.ToString());
    return Ok(new { message = "Success" });
}

Then I create the middleware:

 public async Task Invoke(HttpContext httpContext)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        await _next(httpContext);
        watch.Stop();
        httpContext.Request.Headers.Add("x-time", watch.ElapsedMilliseconds.ToString());
    }

But the result is not the expect, because I can't change the context after the calling to the _next.


Solution

  • You can use HttpResponse.OnStarting method which:

    Adds a delegate to be invoked just before response headers will be sent to the client. Callbacks registered here run in reverse order.

    Something along this lines:

    public async Task Invoke(HttpContext httpContext)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        httpContext.Response.OnStarting(() =>
        {
            watch.Stop();
            httpContext.Response.Headers.Add("x-time", watch.ElapsedMilliseconds.ToString());
            return Task.CompletedTask;
        });
        await _next(httpContext);
        watch.Stop();
    }