Добавление заголовка по умолчанию только для POST-запроса - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь Typed HttpClient, как показано ниже. Я ищу способ добавить DefaultRequestHeaders только к моему запросу POST (а не к другим запросам, таким как GET или PUT). Есть ли способ добиться этого?

Вот мой фрагмент кода.

var builder = services
     .AddHttpClient("MyService", client =>
      {
         client.BaseAddress = configuration.BaseAddress;

         // Need to default header only for "POST" request                    
         client.DefaultRequestHeaders.Add("MyHeader", "MyHeaderValue");
      })
      .AddTypedClient<IMyServiceClient, MyServiceRestClient>();

Я пытаюсь найти способ, где строка client.DefaultRequestHeaders.Add("MyHeader", "MyHeaderValue") эффективна только для запроса POST.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Я на самом деле был здесь глупым. Я понял, что могу достичь того, чего хотел, через DelegatingHandler.

var builder = services
    .AddHttpClient("MyService", client =>
    {
        client.BaseAddress = configuration.BaseAddress;
    })
    .AddHttpMessageHandler<MySpecialHeaderDelegatingHandler>()
    .AddTypedClient<IMyServiceClient, MyServiceRestClient>();





public class MySpecialHeaderDelegatingHandler: DelegatingHandler
{
    private const string MySpecialHeader = "my-special-header";

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        EnsureMySpecialHeaderExists(request);
        return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
    }

    private static void EnsureMySpecialHeaderExists(HttpRequestMessage request)
    {
        if (request.Method != HttpMethod.Post) return;

        if (!request.Headers.Contains(MySpecialHeader))
        {
            request.Headers.Add(MySpecialHeader, "MyHeaderValue");
        }
    }
0 голосов
/ 18 февраля 2020

А как насчет многоразового использования httpclient , который имеет минимальную конфигурацию и затем управляет вашим запросом с помощью метода http1 c выполнение?

Например, рассмотрим asyn c POST метод, который переопределяет внутренний метод generi c asyn c, который конфигурирует запрос / ответ и использует для выполнения ваш httpclient . Вы можете передать нужные заголовки и / или установить заголовки по умолчанию в этом методе.

public async Task<KeyValuePair<HttpResponseMessage, T>> PostAsync<T>(Uri uri, object data, AuthenticationHeaderValue authHeader = null, Dictionary<string, string> headers = null)
{
   return await SendRequestAsync<T, object>(uri.ToString(), data, HttpMethod.Post, authHeader, headers);
}

Внутренний метод выглядит следующим образом:

private async Task<KeyValuePair<HttpResponseMessage, T>> SendRequestAsync<T, U>(string requestUri, U content, HttpMethod method, AuthenticationHeaderValue authHeader = null, Dictionary<string, string> headers = null)
{
    using (HttpRequestMessage request = new HttpRequestMessage())
    {
        request.Method = method;
        request.RequestUri = new Uri(requestUri, UriKind.Absolute);

        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        if (authHeader != null)
        {
            request.Headers.Authorization = authHeader;
        }

        string requestContent = null;

        if (content != null)
        {
            requestContent = JsonConvert.SerializeObject(content);
            request.Content = new StringContent(requestContent, Encoding.UTF8, "application/json");
        }

        if (headers != null)
        {
            foreach (var header in headers)
            {
                if (!request.Headers.Contains(header.Key))
                {
                    request.Headers.Add(header.Key, header.Value);
                }
            }
        }

        // _client would be a private implementation or injected version of your httpclient
        using (HttpResponseMessage response = await _client.SendAsync(request))
        {
            if (response.IsSuccessStatusCode)
            {
                if (response.Content != null)
                {
                    var rawJson = await response.Content.ReadAsStringAsync();

                    var mappedObj = JsonConvert.DeserializeObject<T>(rawJson);

                    var result = new KeyValuePair<HttpResponseMessage, T>(response, mappedObj);

                    return result;
                }
            }
            else
            {
                // do something else
            }

            return new KeyValuePair<HttpResponseMessage, T>(response, default(T));
        }
    }
}
...