【问题标题】:C# HttpClient.SendAsync throw "An error occurred while sending the request" exception when testing some URLsC# HttpClient.SendAsync 在测试某些 URL 时抛出“发送请求时发生错误”异常
【发布时间】:2015-10-04 09:39:49
【问题描述】:

我正在开发一个 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) 
                { 
                }
            }
        }

    }
} 

【问题讨论】:

    标签: c# .net http dotnet-httpclient


    【解决方案1】:

    如果您查看InnerException,您会看到:

    “无法解析远程名称:'www.fc.edu'”

    这个网址在我的浏览器上也不起作用。

    为了获得 HTTP 响应,您需要客户端能够与服务器通信(即使是为了获得 error 404),在您的情况下,错误发生在 at the DNS level

    某些浏览器会自动完成这种情况,如果找不到特定的 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)
    {
    
    }
    

    收件人:

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

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

    另外,除非投掷者抛出了泛型 Exception,否则你永远不应该抓住泛型 Exception,甚至永远不要抓到并且什么都不做除了例外,至少记录一下。

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

    urlTester.RunTestAsync().Wait();
    

    代替:

    Task.WhenAll(urlTester.RunTestAsync());
    

    Task.WhenAll 在给定的Tasks 完成后创建一个新的Task。在您的情况下,您需要 Task.WaitAllTask.WhenAll(...).Wait()

    【讨论】:

    • 一般情况下,Task.WhenAll 会返回一个需要等待的 awaitable。如果他想要阻塞版本,Task.WaitAll 是他应该使用的。
    • 感谢@TamirVered 和 Yuval Itzchakov 帮助我找出异常的细节并改进我的代码。现在问题变成了当这个 DNS 级别问题发生时,我如何知道这个 URL 是否有效。因为在很多情况下,URL 确实有效。查看测试过的 URL 部分,我刚刚添加了这个案例。
    • 您可以再次阅读InnerException 以查看错误原因,并查看InternalStatus 以查看之后的连接状态。
    • "这个 URL 在我的浏览器上也不起作用。" - 这个对我有帮助,我错误地设置了内部 DNS 操作 ;)
    【解决方案2】:

    我解决了这个问题:

    System.Net.ServicePointManager.SecurityProtocol =
                SecurityProtocolType.Tls12 |
                SecurityProtocolType.Tls11 |
                SecurityProtocolType.Tls;
    

    【讨论】:

      猜你喜欢
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-20
      • 1970-01-01
      • 2021-09-09
      • 2015-12-26
      相关资源
      最近更新 更多