I'd be tempted to use a DelegatingHandler
if you need to apply an API key to every single request:
private class KeyHandler : DelegatingHandler
{
private readonly string _escapedKey;
public KeyHandler(string key) : this(new HttpClientHandler(), key)
{
}
public KeyHandler(HttpMessageHandler innerHandler, string key) : base(innerHandler)
{
// escape the key since it might contain invalid characters
_escapedKey = Uri.EscapeDataString(key);
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// we'll use the UriBuilder to parse and modify the url
var uriBuilder = new UriBuilder(request.RequestUri);
// when the query string is empty, we simply want to set the appid query parameter
if (string.IsNullOrEmpty(uriBuilder.Query))
{
uriBuilder.Query = $"appid={_escapedKey}";
}
// otherwise we want to append it
else
{
uriBuilder.Query = $"{uriBuilder.Query}&appid={_escapedKey}";
}
// replace the uri in the request object
request.RequestUri = uriBuilder.Uri;
// make the request as normal
return base.SendAsync(request, cancellationToken);
}
}
Usage:
httpClient = new HttpClient(new KeyHandler(Key));
httpClient.BaseAddress = new Uri($"https://api.openweathermap.org/data/2.5/weather");
// since the logic of adding/appending the appid is done based on what's in
// the query string, you can simply write `?q=mexico` here, instead of `&q=mexico`
using (var response = await ApiHelper.httpClient.GetAsync("?q=mexico"))
** Note: If you're using ASP.NET Core, you should call services.AddHttpClient()
and then use IHttpHandlerFactory
to generate the inner handler for KeyHandler
.