【问题标题】:C# ASP.NET Core - SocketException: No such host is knownC# ASP.NET Core - SocketException:没有这样的主机是已知的
【发布时间】:2021-03-24 17:22:31
【问题描述】:

我遇到的问题似乎与使用 HttpClient 异步调用特定 API 相关 - 奇怪的是它不会一直发生,可以通过刷新页面来解决(有时一次,有时多次)。

我认为这可能是本地问题,但在 Azure 上托管会产生相同的结果。

原始异常详情:

System.Net.Sockets.SocketException (11001):不知道这样的主机 在 System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32 端口,CancellationToken 取消令牌)

我已经检查过:

  • API 没有任何限制
  • 在浏览器中传递请求 url 会返回预期的 JSON 结果
  • 刷新页面有时可以解决问题

错误的开始:

其余的:

这似乎是导致问题的方法:

public async Task<List<MoonPhase.Phasedata>> GetPhaseDataAsync(double lat, double lng, int year)
{
    string requestUrl = "https://api.usno.navy.mil/moon/phase?year=" + year + "&coords=" + locationService.FormatCoordinates(lat, lng) + "&tz=0";

    using (var client = new HttpClient())
    {
        var content = await client.GetStringAsync(requestUrl);
        var moonPhaseObject = JsonConvert.DeserializeObject<MoonPhase.RootObject>(content, new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore
        });

        return moonPhaseObject.PhaseData;
    }
}

【问题讨论】:

  • 首先,将 HttpClient 视为 IDisposable 是一种不好的做法。
  • @TimothyJannace 为什么会这样? HttpClient 实现 IDisposable
  • 您是否检查过呈现的 URL 是否有效,以及运行代码的机器是否可以解析和导航到 api.usno.navy.mil
  • 这篇文章可能有助于解释它。他在底部有一个很好的总结,解释了 HttpClient 的生命周期:medium.com/@nuno.caneco/…

标签: c# asp.net-core asp.net-core-mvc


【解决方案1】:

我通过在 15 分钟内尝试多次访问来测试 API(使用 this URI)。有一两分钟,它似乎有 DNS 问题。

如果出现 DNS 故障 (source) 等问题,GetStringAsync 方法将引发 HttpRequestException 异常。如果抛出此异常,您可以尝试捕获此异常并实施重试机制。

【讨论】:

    【解决方案2】:

    当我将 api url 设置为 'https://www' -> 'https://' 时,问题已解决

    【讨论】:

    • 这对我来说实际上是一个解决方案,因为团队成员使用“https://www.localhost”而不是“https://localhost”
    【解决方案3】:

    什么?这些 cmets 不完全正确,have you read the docs?如果您在 net core 中使用 Httpclient,则应该使用 HttpFactory 或命名或类型化客户端。

    以工厂为例

    services.AddHttpClient();
    

    然后

    public class BasicUsageModel : PageModel
    {
        private readonly IHttpClientFactory _clientFactory;
    
        public IEnumerable<GitHubBranch> Branches { get; private set; }
    
        public bool GetBranchesError { get; private set; }
    
        public BasicUsageModel(IHttpClientFactory clientFactory)
        {
            _clientFactory = clientFactory;
        }
    
        public async Task OnGet()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, 
                "https://api.github.com/repos/aspnet/AspNetCore.Docs/branches");
            request.Headers.Add("Accept", "application/vnd.github.v3+json");
            request.Headers.Add("User-Agent", "HttpClientFactory-Sample");
    
            var client = _clientFactory.CreateClient();
    
            var response = await client.SendAsync(request);
    
            if (response.IsSuccessStatusCode)
            {
                Branches = await response.Content
                    .ReadAsAsync<IEnumerable<GitHubBranch>>();
            }
            else
            {
                GetBranchesError = true;
                Branches = Array.Empty<GitHubBranch>();
            }                               
        }
    }
    

    还有命名客户端和类型客户端。尝试直接使用那些而不是您的 HttpClient,这也有助于解决 DNS 缓存问题。

    【讨论】:

    • 使用部分代码的答案是最好的......“使用工厂,但我不会告诉你如何实际构建这个东西或任何东西......”
    • 这里有很重要的部分,要在startup中添加什么以及如何在类中注入,缺少什么?,如果您有疑问,可以查看文档。
    • 这与找不到主机有什么关系,有人可以帮忙吗?
    猜你喜欢
    • 2011-06-25
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2021-12-08
    • 2021-04-21
    • 1970-01-01
    相关资源
    最近更新 更多