/ asp.net

ASP.NET vNext on Mono Adding X-ElapsedTime response header

In this section we'll cover how to add your own response headers to your WebApi application that was started in this article. If you don't care how the tutorial started, just read ahead, I'm sure there will be some nuggets to get you going.

A few things about the framework here.

  1. Middleware are considered singletons. So be mindful of your scopes when saving state. In most cases you won't see threading issues until your application is under stress. Unfortunately that's the wrong time to figure things out because since it's a race condition, it'll be hard to reproduce. Forewarned is forearmed here.
  2. You can't add headers to the response (that will actually get sent to the client) anywhere after the await _next(context); call.
  3. Use context.Response.OnStarting to bind any code that needs to do any manipulation of the response if you delegate to the next RequestDelegate in the chain. If not, then you can feel free to using the context.Response object directly to do everything

Add Custom Response Headers

Create a new file in your project and paste the below code into it

using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using System.Diagnostics;

public class ElapsedTime 
{
  private RequestDelegate _next;
  public ElapsedTime(RequestDelegate next) 
  {
    _next = next;
  }
	
  public async Task Invoke(HttpContext context) 
  {
    var timer = Stopwatch.StartNew();
    //To add Headers AFTER everything you need to do this
    context.Response.OnStarting(state => {
      var httpContext = (HttpContext) state;
      httpContext.Response.Headers.Add("X-ElapsedTime", new [] { timer.ElapsedMilliseconds.ToString() });
			return Task.FromResult(0);
		}, context);
		
    //Once everything unwinds the OnStarting should get called and we can then record the elapsed time.
    await _next(context);
  }
}

Wiring it into the pipeline of things. In the default generated output from yo aspnet -> Web Api Application you will have a Startup.cs in the root of your project folder.

File: Startup.cs
Method: public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

// Add the platform handler to the request pipeline.
app.UseIISPlatformHandler();

//Lets Add our Custom Middle Ware, These are effectively handlers
app.UseMiddleware<ElapsedTime>();
            
// Configure the HTTP request pipeline.
app.UseStaticFiles();

Ok once you've added the two items, you should be able to start up your app using dnx web and then make a request.
Use curl to test the headers that are returned, in my case my application is localhost:5000 but substitute yours if different

curl -vv http://localhost:5000

Example Output

curl -vv http://localhost:5000/api/values
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET /api/values HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:5000
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 30 Oct 2015 23:41:08 GMT
< Content-Type: application/json; charset=utf-8
* Server Kestrel is not blacklisted
< Server: Kestrel
< X-ElapsedTime: 1
< Transfer-Encoding: chunked

As you can see X-ElapsedTime is returned. It's pretty fast in this case since the application isn't doing anything major. It is interesting to watch the very first request after you app starts. You an see that the first request into the system takes longer than subsequent ones, most likely due to some initial startup.

Next time I'll cover how to add additional headers to the request

ASP.NET vNext on Mono Adding X-ElapsedTime response header
Share this