Search code examples
swagger.net-7.0c#-11.0

How to add a header to a Swagger call, the hard way


I have a Web API with a bunch of methods that does stuff. But this API has a custom middleware section which reads a specific header from each request to check for an API key. If this key is not available then some calls will get blocked. The method itself is not required to use this key.
I then created a second project and imported the service reference and now I want to call these methods. However, the methods don't support adding this key as extra parameter so I need to do something more to include the header in my call. So I have:

HttpClient client = new();    
AccountsClient accounts = new("http://localhost:5401", client);
accounts.LoginAsync("Username", "Password").Wait();

And somewhere in there I need to add the key to this method call to validate that the right application is making this call. (Validate the app before validating the user.) How do I include this header in the client side?
Note: the Web API itself is out of my control and cannot be changed.


Solution

  • As it turns out, including headers (and reading headers) is actually very simple, as the Swagger client generated code is a partial class. So by using this:

    public partial class AccountsClient 
    {
        public string Token { get; set; } = string.Empty;
    
        partial void PrepareRequest(HttpClient client, HttpRequestMessage request, string url)
        {
            request.Headers.Add("Token", Token);
        }
    
        partial void ProcessResponse(HttpClient client, HttpResponseMessage response)
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                Token = string.Join(", ", response.Headers.GetValues("Token"));
            }
        }
    }
    

    I would get a complete and simplified token management. When ProcessResponse gets called, I get a chance to read the headers from the response and save it to some field or property. The Web API can set this header in the response when my code is validating itself as an application and requests an API key. This will memorize the token.
    Then the PrepareRequest can use that token again to pass to the server with every new request. Thus the whole client makes the whole token management automatically managed for me so my client code can just ignore it completely. It's there, in this partial class.
    Of course, that Token property can also be set from my regular code when I have stored the key in my client.
    This provides a very powerful solution in my code, as this token is an encrypted JWT that the client could not read, nor modify without getting flagged. Because this fully manages the token, including the refreshing of the token, I don't have to worry about it any more.
    And I suddenly realized that the Swagger client is full partial classes and methods, allowing me to extend functionality easily. But I expected it to be far more complex but it turns out that the Swagger client gives me easy access to the request and response.