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 шт):
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 у него новый с нуля переписанный сетевой движок.