C#HttpClient.SendAsync在测试某些URL时抛出"发送请求时发生错误"异常

cod*_*ube 25 .net c# http dotnet-httpclient

我正在开发一个C#控制台应用程序,用于测试URL是有效还是有效.它适用于大多数URL,并且可以从目标网站获得HTTP状态代码的响应.但是在测试其他一些URL时,应用程序会在运行HttpClient.SendAsync方法时抛出"发送请求时发生错误"异常.因此,即使此URL实际上在浏览器中有效,我也无法获得任何响应或HTTP状态代码.我迫不及待地想知道如何处理这个案子.如果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) 
                { 
                }
            }
        }

    }
} 
Run Code Online (Sandbox Code Playgroud)

Tam*_*red 19

如果你看一下,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.
Run Code Online (Sandbox Code Playgroud)

但请注意,您可以从以下位置更改代码:

catch (Exception e)
{

}
Run Code Online (Sandbox Code Playgroud)

至:

catch (HttpRequestException e)
{
    Console.WriteLine(e.InnerException.Message);
}
Run Code Online (Sandbox Code Playgroud)

您将能够看到导致错误的原因.

此外,你永远不应该想要捕获泛型,Exception除非投掷者抛出泛型Exception,甚至,永远不会捕获并对异常做任何事情,至少记录它.

请注意,因为您只等待那一项任务,您可以使用:

urlTester.RunTestAsync().Wait();
Run Code Online (Sandbox Code Playgroud)

代替:

Task.WhenAll(urlTester.RunTestAsync());
Run Code Online (Sandbox Code Playgroud)

Task.WhenAllTask当给定的Tasks完成时创建一个新的.在你的情况下,你需要Task.WaitAllTask.WhenAll(...).Wait().


Huy*_*Huy 15

我解决了这个问题:

System.Net.ServicePointManager.SecurityProtocol =
            SecurityProtocolType.Tls12 |
            SecurityProtocolType.Tls11 |
            SecurityProtocolType.Tls;
Run Code Online (Sandbox Code Playgroud)