Отправить запрос HttpClient без DefaultRequestHeaders - PullRequest
0 голосов
/ 17 мая 2018

Я работаю с плохо спроектированным API, и среди его недостатков у него есть одна конкретная конечная точка, которая не должна давать определенный пользовательский заголовок, в то время как буквально каждая другая конечная точка требует этого. В результате он включен в DefaultRequestHeaders, поэтому мне не нужно добавлять его вручную к каждому запросу.

Однако сейчас для этой конкретной конечной точки мне нужно удалить ее, и я не уверен, как или если это вообще возможно. В некоторой степени все усложняется, я имею дело с экземпляром HttpClient в одиночной области действия, так что любые попытки с DefaultRequestHeaders не нужны. Другими словами, я не могу сделать что-то хакерское, например временно удалить заголовок, а затем добавить его обратно после запроса, потому что это может повлиять на выполнение других параллельных запросов. К сожалению, даже если я использую SendAsync с пользовательским экземпляром HttpRequestMessage, HttpClient все еще добавляет заголовок.

Кроме того, хотя это будет работать, я бы действительно предпочел не вводить другой экземпляр HttpClient без заголовка, добавленного к DefaultRequestHeaders. Работа с двумя разными HttpClient экземплярами в одном и том же классе кажется просто ужасной идеей по многим причинам.

Мне здесь не повезло, или есть какое-то решение, которое я упустил после того, как обыскивал Меж сети в течение последнего часа?

UPDATE

Одна вещь, которую я действительно нашел, что с пользовательским экземпляром HttpRequestMessage, я могу по существу очистить заголовок, установив его в пустую строку на HttpRequestMessage. Так как это явно установлено, HttpClient не перезаписывает его версией по умолчанию. Это по-прежнему означает, что заголовок отправляется, но, по крайней мере, он на самом деле не имеет значения. Тем не менее, все еще заинтересованы в лучшем решении, если оно существует.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Возможно, это не тот ответ, который вы ищете, но если вы не хотите отправлять заголовок при каждом вызове, я бы не стал использовать DefaultRequestHeaders для него вообще.Мне кажется, что взломать его «вручную», когда вам это нужно, - это не такая хакерская попытка, как удаление одной конечной точки.

Конечно, вы хотите, чтобы она была СУХОЙ.Не видя ваш код, предполагая, что вы делаете все вызовы API из одного класса, одной из возможностей будет просто создать частный вспомогательный метод, подобный этому, который все остальные методы будут использовать для:

HttpRequestMessage BuildRequestMessage(object body, bool sendCustomHeader = true)

Или, может быть, помощник, который также принимает глагол и конечную точку и фактически отправляет запрос.

В качестве альтернативы, если вы хотите убрать этот «шум» из основного класса оболочки API, вы можете создать обработчик, как в @Ответ Эка, за исключением того, что я снова пропустил бы, используя DefaultRequestHeaders и переключив логику на , включая заголовок, если вы не вызываете конкретную конечную точку.

0 голосов
/ 18 мая 2018

Вы можете сделать это внутри переопределения обработчика SendAsync, потому что на данный момент HttpClient уже добавил заголовки по умолчанию к вашему запросу. Если вы не используете пользовательский обработчик - вы можете наследовать от HttpClientHandler и использовать его, потому что new HttpClient() совпадает с new HttpClient(new HttpClientHandler()). Например:

public static void Main(string[] args) {
    HttpClient c = new HttpClient(new MyHttpClientHandler());
    c.DefaultRequestHeaders.Add("X-Test", "1");
    var res = c.GetAsync("http://google.com").Result;
}

class MyHttpClientHandler : HttpClientHandler {
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        // check for your endpoint
        if (request.RequestUri.Host == "google.com") {
            // remove
            request.Headers.Remove("X-Test");
        }

        return base.SendAsync(request, cancellationToken);
    }
}
...