Propagate headers with .NET Core Web API
Tags: tutorial, csharp, dotnet, api
Published: 2020-10-16 21:29:52


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](https://dev-to-uploads.s3.amazonaws.com/i/77ikglpv5s1ap2crehrx.png)

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:

```bash
dotnet new webapi --name HeaderPropagationDemo --language "C#"
```

### Step 2: Install HeaderPropagation package

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

```bash
dotnet add package Microsoft.AspNetCore.HeaderPropagation --version 3.1.8
```

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

```bash
dotnet add package HeaderPropagation --version 3.0.2
```

### Step 3: Setup Dependency Injection

Enable middleware on _Startup.Configure_ using:
```csharp
app.UseHeaderPropagation();
```

Then add the service onto _Startup.ConfigureServices_:

```csharp
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](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1), you need to add a delegating handler to every client, like this:

```csharp
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](https://httpbin.org/) GET method which in turn will send us the headers we propagated onto him.

```csharp
[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](https://www.postman.com/).

----------

### Wrap up

That’s it. Hope this has helped you in any way.  
Have a nice day!