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:
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#"
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
If you’re using a lower version, add this one:
dotnet add package HeaderPropagation --version 3.0.2
Step 3: Setup Dependency Injection
Enable middleware on Startup.Configure using:
app.UseHeaderPropagation();
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");
});
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();
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());
}
}
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!
Top comments (1)
Hello, Nuno! Thank you for your explanation. Does it make a difference where app.UseHeaderPropagation is placed? Sometimes the order of middleware usage is critical.