C# .NET4 Как валидировать локальную ошибку при запросе POST?

Цель следующая, отправить запрос и получить данные(получение данных опустим)

Если не будет инетрнета на компьютере то вывести об этом ошибку

Если интернет есть но очень слабый получить таймаут и вывести его

По идеи все просто...

namespace WebClientTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            HttpWebRequest httpWebRequest;
            HttpWebResponse httpResponse = null;

            try
            {
                httpWebRequest = (HttpWebRequest)WebRequest.Create("http://8.8.8.8/");

                httpWebRequest.Method = "POST";
                httpWebRequest.Timeout = 30000;
                httpWebRequest.ContinueTimeout = 10000;
                try
                {
                    httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                }
                catch (WebException ex)
                {
                    Console.WriteLine("WebException: " + ex.Status.ToString());
                    Console.WriteLine("WebException: " + ex.Message);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.Message);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }
}

Выключаю сетевой адаптер и через 20сек WebException выдает:

WebException: ConnectFailure

WebException: Невозможно соединиться с удаленным сервером Если ограничиваю скорость минимально, получаю тоже самое

От сюда вопросы

Почему ConnectFailure именно через 20сек когда указан таймаут до 30сек?

Почему ConnectFailure если скорость просто ограничена до 64кб и ниже? по идеи должно быть timeout

Возможно ли вообще различить отсутсвие интернета и плохое соединение не прибегая к стороним библиотекам и пингованием того же гугла?

PS Если указать таймаут менее 20сек то будет именно он в двух случаях когда инетнета нету или плохое соединение

В конечно счете хотела увидеть:

При отсутствии интернета ConnectFailure

При ограниченном интернете timeout


Ответы (1 шт):

Автор решения: aepot

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

Начиная с .NET Framework 4.5 следует использовать для работы с сетью современный клиент HttpClient. Хотя мой вам совет, если уж потребовался древний фреймворк, то не используйте версии старше, чем 4.6, более старшие версии несовместимы с интернетом, и чтобы они заработали, придется обвешиваться костылями, но лучше использовать 4.7.2 и новее.

POST запрос должен содержать тело, то есть контент, от типа этого контента сильно зависит код, который надо написать, но вот вам заготовка. Пусть это будет какой-то текст для отправки, например JSON.

static readonly HttpClient client = new HttpClient();

static async Task Main(string[] args)
{
    string json = "{ \"message\": \"Hello World\" }";
    string url = "https://my.host";
    try
    {
        using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url))
        {
            request.Content = new StringContent(json, "application/json", Encoding.UTF8);
            using (HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
            {
                Console.WriteLine($"{(int)response.StatusCode} {response.ReasonPhrase}");
                response.EnsureSuccessStatusCode();
                string result = await response.Content.ReadAsStringAsync();
                Console.WriteLine(result);
            }
        }
    }
    catch (HttpRequestException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

(с трудом вспомнил как оно пишется на старом C# 7.x)

И не заморачивайтесь с таймаутами. Сначала освойте инструмент в рабочем режиме. Ну и поизучайте асинхронное программирование.

.NET 4.x кстати тоже устарел. Еще полезный эффект, если вы перейдете на современные дотнеты, HttpClient внезапно начнет поддерживать HTTP/2 и прочие современные плюшки, да и работать станет быстрее. Начиная с .NET Core 3.1 у него новый с нуля переписанный сетевой движок.

→ Ссылка