Propagate headers with .NET Core Web API

no0law1

Nuno Reis

Posted on October 16, 2020

Propagate headers with .NET Core Web API

Welcome. Today we are going to learn how to propagate any header you receive onto another HTTP service using .NET Core Web API.


Let’s say I have a pipeline which consists of three services, like this:

Alt Text

And I want my service at the end of the line to receive the headers that were sent from the client that requested information from the service at the beginning of the line.

How is this useful in real life? Well, imagine your service down the line needs the accept-language sent from the client to access some information that is language-specific. Propagating the headers is one way to achieve that the service down the line will receive that header.

Let’s see how we can achieve this with a simple solution that requires no workarounds.


Step 1: Create your Web API

You can create it using the command:

dotnet new webapi --name HeaderPropagationDemo --language "C#"
Enter fullscreen mode Exit fullscreen mode

Step 2: Install HeaderPropagation package

If you’re already using .NET Core 3.1, add this package:

dotnet add package Microsoft.AspNetCore.HeaderPropagation --version 3.1.8
Enter fullscreen mode Exit fullscreen mode

If you’re using a lower version, add this one:

dotnet add package HeaderPropagation --version 3.0.2
Enter fullscreen mode Exit fullscreen mode

Step 3: Setup Dependency Injection

Enable middleware on Startup.Configure using:

app.UseHeaderPropagation();
Enter fullscreen mode Exit fullscreen mode

Then add the service onto Startup.ConfigureServices:

services.AddHeaderPropagation(o =>  
{  
    // Add Default   
    o.Headers.Add("User-Agent", context => "HeaderPropagationDemo");  
    // Propagate if header exists  
    o.Headers.Add("Accept-Language");  
});
Enter fullscreen mode Exit fullscreen mode

I’ve only added two specific examples. One for User-Agent where I can specifically define it so it can be added if there is no User-Agent present and the Accept-Language header with no default value.

This is pretty much all you need for a basic setup to propagate the headers you want.

Step 4: Setup a Client (optional)

If you are using HttpClientFactory, you need to add a delegating handler to every client, like this:

services.AddHttpClient("DefaultClient")  
    .AddHeaderPropagation();
Enter fullscreen mode Exit fullscreen mode

Step 5: See it actually working

Let’s create a controller with an endpoint capable of making a request to one of the httpbin.org GET method which in turn will send us the headers we propagated onto him.

[ApiController]  
[Route("[controller]")]  
public class PropagationController : ControllerBase  
{  
    private readonly IHttpClientFactory _factory;  

    public PropagationController(IHttpClientFactory factory)  
    {  
        _factory = factory;  
    }  

    [HttpGet]  
    public async Task<IActionResult> Get()  
    {  
        var client = _factory.CreateClient("DefaultClient");  

        var result = await client.GetAsync("https://httpbin.org/get");  

        return Ok(await result.Content.ReadAsStringAsync());  
    }  
}
Enter fullscreen mode Exit fullscreen mode

Run your API and make a request to this endpoint. You should receive a response with the headers. Try not passing any User-Agent and if you’ve followed everything correctly, you should be able to see the default value provided on the code.

Using the browser may be a little tricky to modify the headers, you can use an extension for Chrome for example, but I personally use Postman.


Wrap up

That’s it. Hope this has helped you in any way.

Have a nice day!

💖 💪 🙅 🚩
no0law1
Nuno Reis

Posted on October 16, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related