HttpClient — один и тот же код дает разные исключения в .NET Framework и .NET 5.0

#c# #.net-5 #.net-framework-version

Вопрос:

Я пытаюсь обновить проект .net framework 4.5 до .net 5.0, но столкнулся с проблемой. После некоторой головной боли я обнаружил, что это HttpClient.GetAsync(). Это дает мне разные исключения в зависимости от целевой платформы.

В .NET Framework 4.5 я получаю следующее исключение: (Правильное поведение) «При отправке запроса произошла ошибка». С внутренним исключением «Запрос был прерван: не удалось создать безопасный канал SSL/TLS».

В то время как в .NET 5.0 я получаю следующее: «Запрос был отменен из-за настроенного HttpClient.Время ожидания составляет 100 секунд.» с внутренним исключением «Операция ввода-вывода была прервана либо из-за выхода из потока, либо из-за запроса приложения».

Проблема в том, что приложение вообще не получает ответа в .NET 5.0, в то время как в .NET Framework 4.5 оно немедленно выдает исключение.

У меня есть следующий фрагмент кода:

 string deviceAddress = "https://192.168.1.173:443";  HttpClientHandler httpClientHandler = new HttpClientHandler();  HttpClient httpClient = new HttpClient(httpClientHandler);  Uri uri = new Uri(deviceAddress);   try  {  HttpResponseMessage response = await httpClient.GetAsync(uri);  }  catch (Exception ex)  {  Debug.WriteLine(ex.Message);  }  

Пожалуйста, посоветуйте, я новичок в .NET 5.0.

Я попробовал «AcceptAllCertificates». В .NET Framework 4.5 исключение исчезает, как и ожидалось, но в .NET 5.0 разницы нет, функция никогда не вызывается.

 httpClientHandler.ServerCertificateCustomValidationCallback = AcceptAllCertificates;   protected bool AcceptAllCertificates(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) {  return true; }  

Комментарии:

1. .NET 5-это .NET Core 5. HttpClient сильно изменился в .NET Core и на самом деле намного лучше. Между тем AcceptAllCertificates , это ужас безопасности, который делает HTTPS бесполезным — HTTPS не используется для шифрования сообщений, он используется для обеспечения того, чтобы ничто не могло встать между ними, выдавать себя друг за друга и, таким образом, перехватывать сообщения. Это делается путем проверки сертификатов перед подключением

2. Если вам пришлось отключить проверку сертификатов в .NET Framework, это означает, что вы уже использовали недействительный сертификат. Возможно, самоподписанный сертификат разработки. Решение этой проблемы заключается не в отключении проверки сертификата, а в добавлении этого сертификата в список надежных сертификатов. В .NET Core SDK сам генерирует и регистрирует самозаверяющий сертификат для разработки.

3. PS: код, который вы использовали, очень необычен. Вам не должно понадобиться ничего большего, кроме того, что HttpClient _client=new HttpClient(); ..... var response=await httpClient.GetAsync("https://192.168.1.173"); нет причин указывать порт.

4. The I/O operation has been aborted because of either a thread exit or an application request. каков фактический, полный текст исключения и фактический код ? Это может означать, что ваше приложение завершилось, когда асинхронный метод все еще выполнялся. Или что время ожидания запроса истекло, потому что служба не ответила вовремя. Если эта служба написана на .NET (Core) 5, она использует доверенный сертификат разработки, поэтому нет причин создавать исключение недопустимого сертификата

5. Привет, Панайотис, спасибо за ваши быстрые ответы! Я знаю, что использую недействительный сертификат. Разница здесь в том, что в .net framework я получаю исключение, в то время как в .net (core) 5 я этого не делаю.

Ответ №1:

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

Проблема в данном случае, скорее всего, связана с проблемой VPN. «Исправление» в этом случае состояло в том, чтобы просто установить тайм-аут на низкое значение:

 httpClient.Timeout = TimeSpan.FromSeconds(4.0);  

Таким образом, вместо этого я получаю исключение тайм-аута через приемлемое количество времени. Это, конечно, не решение, а обходной путь.