Https приводит к исключению при использовании HttpClient - PullRequest
0 голосов
/ 30 апреля 2020

У меня проблема с вызовом моего ASP. NET Web API из клиентского приложения. Здесь было задано много вопросов, касающихся этой темы c, но ни один из ответов не решил мою проблему.

Проблема:

Когда я пытаюсь вызвать свой API, я получаю следующее исключение:

System. Net .Sockets.SocketException: существующее соединение было принудительно закрыто удаленным хостом

Информация:

  • Оба проекта (cleint и API) основаны на. NET 4.5.2
  • В моей тестовой среде клиент и API работают на одной и той же виртуальной машине
  • Все работало нормально без https
  • Я создал самоподписанный сертификат для тестирования, но ни один браузер не показывает предупреждение, поэтому кажется, что все в порядке

Код:

HttpClient client = new HttpClient();

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

client.BaseAddress = new Uri(apiBaseUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsJsonAsync("call/CreateNew", call);

Я попробовал несколько решений, представленных в ответах на подобные вопросы, но пока ни одно из них не сработало:

  • Использование. NET Framework 4.6 instread 4.5.2
  • Указан протокол с ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
  • Пробовал ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; (просто чтобы быть уверенным) * 10 41 *

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

В любом случае я обнаружил сегменты с надписью " ACKed сегмент, который не был захвачен " и " Предыдущие сегменты не захвачены ", из которых второй содержал данные I на самом деле пытался отправить в мой API.

Можете ли вы дать мне несколько советов, что делать дальше или как исправить эту ошибку?

1 Ответ

0 голосов
/ 30 апреля 2020

Прежде всего убедитесь, что HttpClient был создан один раз для всего срока службы приложения и не был утилизирован. Ошибка - создание new HttpClient() за запрос. См. details .

А вот пример метода, который поддерживает как GET , так и POST HTTP-запросы.

HttpClient client = new HttpClient();

private async Task<string> CallEndpointAsync(string method, string url, string request = "")
{
    // earlier TLS versions may cause issues
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

    switch (method)
    {
        case "POST":
            using (HttpContent content = new StringContent(request))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                using (HttpResponseMessage response = await client.PostAsync(url, content).ConfigureAwait(false))
                {
                    response.EnsureSuccessStatusCode(); // throw an exception for 404, 403, etc.
                    return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                }
            }
        case "GET":
            using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }
        default:
            throw new NotImplementedException("Method " + method + " not supported");
    }
}

Использование

string request = ""; // put Json string here
// in async code
string result = await CallEndpointAsync("POST", "https://example.org/api/method", request);

// sync-over-async
string result = CallEndpointAsync("POST", "https://example.org/api/method", request).GetAwaiter().GetResult();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...