web-dev-qa-db-fra.com

C # HttpClient.SendAsync lance une exception "Une erreur s'est produite lors de l'envoi de la demande" lors du test de certaines URL

Je suis en train de développer une application console C # pour vérifier si une URL est valide ou fonctionne. Cela fonctionne bien pour la plupart des URL et peut obtenir une réponse avec le code d'état HTTP du site Web cible. Mais lors du test d'autres URL, l'application génère une exception "Une erreur s'est produite lors de l'envoi de la requête" lors de l'exécution de la méthode HttpClient.SendAsync. Je ne peux donc pas obtenir de réponse ni de code d'état HTTP même si cette URL fonctionne réellement dans le navigateur. Je suis désespéré de savoir comment gérer cette affaire. Si l'URL ne fonctionne pas ou si le serveur rejette ma demande, il doit au moins me donner le code d'état HTTP correspondant.

Voici le code simplifié de mon application de test:

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) 
                { 
                }
            }
        }

    }
} 
24
codigube

Si vous regardez le InnerException, vous verrez que:

"Le nom distant n'a pas pu être résolu: 'www.fc.edu'"

Cette URL ne fonctionne pas non plus sur mon navigateur.

Pour obtenir une réponse HTTP, le client doit pouvoir communiquer avec le serveur (même pour obtenir erreur 404 ) et dans votre cas, l'erreur est survenue au niveau DNS .

Certains navigateurs utilisent la saisie semi-automatique pour ce type de cas où, si aucune URL spécifique n'est trouvée, le navigateur essaie de nouveau avec un suffixe/préfixe différent, par exemple:

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.

Mais notez que vous pouvez changer votre code de:

catch (Exception e)
{

}

À:

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

Et vous pourrez voir ce qui cause votre erreur.

En outre, Vous ne devriez jamais vouloir attraper le générique Exception à moins que le lanceur n'ait jeté le générique Exception, et même que, ne jamais attraper et ne rien faire à l'exception, au moins le connecter.

Notez que puisque vous n'attendez que pour cette tâche, vous pouvez utiliser:

urlTester.RunTestAsync().Wait();

Au lieu de:

Task.WhenAll(urlTester.RunTestAsync());

Task.WhenAll Crée un nouveau Task lorsque les Tasks donnés sont terminés. dans votre cas, vous avez besoin de Task.WaitAll ou Task.WhenAll(...).Wait().

19
Tamir Vered