In this article, we are going to learn about the different ways we can extract Custom Headers from our ASP.NET Core Web API requests.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

What Are HTTP Headers?

HTTP headers are part of every HTTP request in both the request and response data.

It contains metadata information such as security authentication information, the agent used, and cache control. In our requests, we can already find some predefined HTTP headers, however, we can use custom HTTP headers if needed.

To see what headers look like, we can inspect a full HTTP header request from Postman:

GET /api2/headers/from-middleware HTTP/1.1
CustomHeaderKey: CustomHeaderValue
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Postman-Token: 78eb9192-ce96-421c-879c-1a4eae8e2303
Host: localhost:7202
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

The first line is the request and the rest are HTTP headers. That is to say, the method, route, and protocol are the elements that make up the request.

And in this request, we can see a CustomHeaderKey custom header with its value.

Now we can start to explore options to extract the headers and use them in controllers, filters, or middlewares.

Basic HTTP Header Extraction

Manipulating with HTTP headers in ASP.NET Core is easy enough to do as part of an execution that has access to the Request.Headers dictionary.

In ASP.NET Core, the IHeaderDictionary is the interface that defines the HTTP request headers. These headers comprise a key-value pairs dictionary. The header keys are strings and the header values are StringValues structs:

[HttpGet("from-basic")] 
public IActionResult ExtractFromBasic() 
{ 
   const string HeaderKeyName = "HeaderKey"; 
   Request.Headers.TryGetValue(HeaderKeyName, out StringValues headerValue); 

   return Ok(headerValue); 
}

In this action, we declare a HeaderKeyName constant with the custom header name, and we access the Headers dictionary through the  HTTP Request object. Then, we extract a header, with the name of HeaderKey, invoke the TryGetValue method and set the value to the headerValue variable.

Testing Basic HTTP Header Extraction

We are going to test our endpoint by using Postman:

postman custom header individual request

We can see, we have a GET request to our endpoint, and we also set a custom HeaderKeyheader with its HeaderValue value.

Attribute HTTP Header Extraction

ASP.NET Core introduces the FromHeader attributes: 

Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<
[HttpGet("from-header-attribute")]
public IActionResult ExtractFromQueryAttribute([FromHeader] HeaderDTO headerDTO)
{
    return Ok(headerDTO);
}

We use the FromHeader attribute to specify that a parameter or property should be bound using the request headers.

Of course, for this to work, we need the HeaderDTO class:

public class HeaderDTO
{
    [FromHeader]
    public string FirstName { get; set; } = string.Empty;
    [FromHeader]
    public string LastName { get; set; } = string.Empty;
}

By using the FromHeader attribute, we will bind every property of the HeaderDTO object to the HTTP request headers.

Testing Attribute HTTP Header Extraction

Again, let’s use Postman to send a GET request with the FirstName and LastName custom headers to our new endpoint: https://localhost:7202/api/headers/from-header-attribute.

In the response, we can find the custom headers: FirstName and LastName.

Custom Header Extraction Using Action Filter

If we want to ensure the extraction of any custom header in any endpoint in our ASP.NET Core Web API,  we can use ASP.NET Core action filters.

An action filter is another possibility that we have to extract a custom header value before an action is invoked:

public class ExtractCustomHeaderAttribute : ActionFilterAttribute
{
   public override void OnActionExecuting(ActionExecutingContext context)
   {
      const string HeaderKeyName = "FilterHeaderKey";
      context.HttpContext.Request.Headers.TryGetValue(HeaderKeyName, out StringValues headerValue);
      if (context.HttpContext.Items.ContainsKey(HeaderKeyName))
      {
         context.HttpContext.Items[HeaderKeyName] = headerValue;
      }
      else
      {
         context.HttpContext.Items.Add(HeaderKeyName, $"{headerValue}-received");
      }
   }
}

The ExtractCustomHeaderAttribute class inherits from ActionFilterAttribute, which allows us to use it as an attribute [ExtractCustomHeader]. It also allows us the override the OnActionExecutingmethod, which is called before the action method is invoked. In this method, we use the context.HttpContext.Items dictionary to store the custom header value.

Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<

Once we have the header key/value pair in the dictionary, we can extract it in our action:

[HttpGet("from-filter")]
[ExtractCustomHeader]
public IActionResult ExtractFromFilter()
{
   const string HeaderKeyName = "FilterHeaderKey";
   HttpContext.Items.TryGetValue(HeaderKeyName, out object? filterHeaderValue);

   return Ok(filterHeaderValue);
}

We use theExtractCustomHeader attribute to execute the action filter, that sets the header key/value to the Items dictionary. We can use this attribute at multiple endpoints, and also at the Controller level. Inside the action, we just extract the header value and return it as a result.

Custom Header Extraction Using Middleware

We can also use ASP.NET Core middleware to extract headers in ASP.NET Core.

Let’s create a super-simple middleware to extract the custom header value in the Program.cs class:

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api2"), appBuilder =>
{
    appBuilder.UseMiddleware<ExtractCustomHeaderMiddleware>();
});

The UseWhen allows us to “branch” the pipeline. We can use it to conditionally invoke middleware based on the request path. In other words, if the request path starts with the given path, we will execute our middleware.

And after registering our middleware we can implement:

public class ExtractCustomHeaderMiddleware
{
   private readonly RequestDelegate _next;

   public ExtractCustomHeaderMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
       const string HeaderKeyName = "MiddlewareHeaderKey";
       context.Request.Headers.TryGetValue(HeaderKeyName, out StringValues headerValue);
       if (context.Items.ContainsKey(HeaderKeyName))
       {
          context.Items[HeaderKeyName] = headerValue;
       }
       else
       {
          context.Items.Add(HeaderKeyName, $"{headerValue}-received");
       }

       await _next(context);
    }
}

Here, we implement the InvokeAsync method, which gives us access to the current HttpContext. Furthermore, we can use this HttpContext to add our custom header value and the next Task to execute in the pipeline.

Conclusion

In this article, we’ve learned how to extract a custom header to our ASP.NET Core Web API request using four different strategies.

Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<