C # HttpClient.SendAsync throw Произошла ошибка при отправке исключения запроса при тестировании некоторых URL-адресов

Я разрабатываю консольное приложение C # для проверки того, действителен ли URL или работает. Он хорошо работает для большинства URL-адресов и может получать ответ с кодом состояния HTTP с целевого веб-сайта. Но при тестировании некоторых других URL-адресов приложение выдает исключение «Произошла ошибка при отправке запроса» при запуске метода HttpClient.SendAsync. Поэтому я не могу получить никакого ответа или кода состояния HTTP, даже если этот URL-адрес действительно работает в браузере. Я отчаянно пытаюсь выяснить, как поступить с этим делом. Если URL-адрес не работает или сервер отклоняет мой запрос, он должен, по крайней мере, предоставить мне соответствующий код состояния HTTP.

Вот упрощенный код моего тестового приложения:

using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace TestUrl
{
    class Program
    {
        static void Main(string[] args)
        {
           // var urlTester = new UrlTester("http://www.sitename.com/wordpress"); // works well and get 404
           // var urlTester = new UrlTester("http://www.fc.edu/"); // Throw exception and the URL doesn't work
           var urlTester = new UrlTester("http://www.ntu.edu.tw/english/"); // Throw exception and the URL works actually

            Console.WriteLine("Test is started");

            Task.WhenAll(urlTester.RunTestAsync());

            Console.WriteLine("Test is stoped");
            Console.ReadKey();
        }


        public class UrlTester
        {
            private HttpClient _httpClient;
            private string _url;

            public UrlTester(string url)
            {
                _httpClient = new HttpClient();
                _url = url;
            }

            public async Task RunTestAsync()
            {
                var httpRequestMsg = new HttpRequestMessage(HttpMethod.Head, _url);

                try
                {
                    using (var response = await _httpClient.SendAsync(httpRequestMsg, HttpCompletionOption.ResponseHeadersRead))
                    {
                        Console.WriteLine("Response: {0}", response.StatusCode);
                    }
                }
                catch (Exception e) 
                { 
                }
            }
        }

    }
} 

person codigube    schedule 04.10.2015    source источник


Ответы (1)


Если вы посмотрите на InnerException, вы увидите, что:

«Не удалось разрешить удаленное имя: 'www.fc.edu'»

Этот URL-адрес также не работает в моем браузере.

Чтобы получить ответ HTTP, вам необходимо, чтобы клиент мог связываться с сервером (даже для того, чтобы получить ошибка 404), а в вашем случае ошибка произошла на уровне DNS.

В некоторых браузерах есть автозаполнение для таких случаев, когда, если конкретный URL-адрес не найден, браузер повторяет попытку с другим суффиксом / префиксом, например:

try "x"
if didn't work, try "www." + x
if this didn't work try "www." + x + ".com"
if this didn't work try "www." + x + ".net"
if this didn't work try "www." + x + "." + currentRegionSuffix.

Но обратите внимание, что вы можете изменить свой код из:

catch (Exception e)
{

}

To:

catch (HttpRequestException e)
{
    Console.WriteLine(e.InnerException.Message);
}

И вы сможете увидеть, что вызывает вашу ошибку.

Кроме того, Вы никогда не должны захватывать общий Exception, если метатель не выбросил общий Exception, и даже после этого никогда не перехватывайте и ничего не делайте с исключением, по крайней мере, регистрировать Это.

Обратите внимание: поскольку вы ждете только одну задачу, которую вы можете использовать:

urlTester.RunTestAsync().Wait();

Вместо того:

Task.WhenAll(urlTester.RunTestAsync());

Task.WhenAll создает новый Task по завершении заданных Task. в вашем случае вам понадобится Task.WaitAll или Task.WhenAll(...).Wait().

person Tamir Vered    schedule 04.10.2015
comment
Как правило, Task.WhenAll возвращает ожидаемый объект, который необходимо дождаться. Если ему нужна блокирующая версия, Task.WaitAll - это то, что он должен использовать. - person Yuval Itzchakov; 04.10.2015
comment
Спасибо @TamirVered и Ювалу Ицчакову, которые помогли мне выяснить подробности исключения и улучшить мой код. Теперь возникает вопрос, как я могу узнать, работает ли этот URL-адрес или нет, когда возникает проблема с уровнем DNS. Потому что во многих случаях URL-адрес действительно работает. Ознакомьтесь с протестированной частью URL, я только что добавил этот случай. - person codigube; 04.10.2015
comment
Вы можете прочитать InnerException еще раз, чтобы увидеть причину ошибки, и InternalStatus, чтобы увидеть статус вашего соединения после нее. - person Tamir Vered; 04.10.2015
comment
Этот URL-адрес также не работает в моем браузере. - Этот мне помог, я неправильно настроил внутренний DNS op;) - person Squazz; 27.01.2017