system.net.webeexception:远端名称无法解析

本文关键字:net webeexception system | 更新日期: 2023-09-27 18:15:28

我正在测试一个端点,我遇到了一些问题。

我只是在每小时执行一个请求的循环中使用HttpClient

var httpClient = new HttpClient();
var message = httpClient.GetAsync(url).Result;
Console.WriteLine(message.StatusCode);

有一次我得到这个异常:

System.Net.Http。HttpRequestException:发送时发生错误请求。--> system.net.webeexception:远端名称不能解析:'xxx'

经验是,在异常之后,URL可以被访问。在浏览器中,你只需刷新页面,一切都很好。

我仍然没有收到任何用户的报告,所以我想知道这是否只是一个本地问题,但可以使用一些信息来帮助诊断。

是否有方法检查远程名称无法解析是由DNS问题或由例外的web服务器问题引起的?我是否可以从HttpCLient中获得更多信息,或者我是否需要更高级的诊断工具?

system.net.webeexception:远端名称无法解析

这可能是由本地网络连接问题引起的(也可能是DNS错误)。不幸的是,HResult是通用的,但是你可以确定捕获HttpRequestException的确切问题,然后检查InnerException:如果它是WebException,那么你可以检查WebException.Status属性,例如WebExceptionStatus.NameResolutionFailure应该指示DNS解析问题。


有可能发生,你无能为力。

我建议总是用try/catch块将(与网络相关的)代码包装在循环中(此处也建议用于其他易出错的操作)。处理已知的异常,等待一会儿(比如1000毫秒),然后再试一次(比如3次)。只有当所有时间都失败时,你才能退出/向用户报告错误。非常原始的例子如下:
private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;
public static async Task<HttpResponseMessage> GetFromUrlAsync(string url) {
    using (var client = new HttpClient()) {
        for (int i=1; i <= NumberOfRetries; ++i) {
            try {
                return await client.GetAsync(url); 
            }
            catch (Exception e) when (i < NumberOfRetries) {
                await Task.Delay(DelayOnRetry);
            }
        }
    }
}

我在尝试访问服务(旧的ASMX服务)时遇到了类似的问题。当通过IP访问时,调用将工作,但是当使用别名调用时,我会得到无法解析的远程名称。

将以下内容添加到配置中,并解决了此问题:

<system.net>
    <defaultProxy enabled="true">
    </defaultProxy>
</system.net>

打开位于:**C:'windows'system32'drivers'etc**的hosts文件。

Hosts文件是用来做什么的?

在文件末尾添加以下内容:

YourServerIP YourDNS

的例子:

198.168.1.1 maps.google.com

这个问题肯定与c#的HttpClient有关。这个客户机被设计为重用它。因为在处理HttpClient之后,套接字不会直接关闭。这篇博文(https://www.nimaara.com/beware-of-the-net-httpclient/)提供了很好的解释。

你必须处理你的DNS查找表过时的情况。在博客文章中,你也可以找到如何做到这一点的信息。

ServicePointManager.FindServicePoint(endpoint).ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;

ServicePointManager.DnsRefreshTimeout = (int)1.Minutes().TotalMilliseconds;