C# HttpClient.SendAsync 在测试某些 URL 时抛出“发送请求时发生错误”异常
Posted
技术标签:
【中文标题】C# HttpClient.SendAsync 在测试某些 URL 时抛出“发送请求时发生错误”异常【英文标题】:C# HttpClient.SendAsync throw "An error occurred while sending the request" exception when testing some URLs 【发布时间】: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)
【问题讨论】:
【参考方案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
在给定的Task
s 完成后创建一个新的Task
。在您的情况下,您需要 Task.WaitAll
或 Task.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;
【讨论】:
以上是关于C# HttpClient.SendAsync 在测试某些 URL 时抛出“发送请求时发生错误”异常的主要内容,如果未能解决你的问题,请参考以下文章
在 HttpClient.SendAsync() 之后无法访问已释放的对象
HttpClient.SendAsync() 未将 JSON 作为字符串发送
HttpClient.SendAsync:500 - Windows 服务应用程序中的内部服务器错误
HttpClient.SendAsync 方法退出而不抛出异常
HttpClient.SendAsync 在 Xamarin.Forms Android 上引发 ObjectDisposedException,但在 UWP 上却没有