【问题标题】:"No such host is known" when publishing locally, but not when debugging in Visual Studio在本地发布时“没有这样的主机是已知的”,但在 Visual Studio 中调试时不知道
【发布时间】:2020-04-21 19:21:59
【问题描述】:

相关:No such host is known —> System.Net.Http.HttpRequestException:

所以,我有一个奇怪的问题:每当我使用 HttpClient 对 RESTful API 执行任何调用时,都会收到以下错误:System.Net.Http.HttpRequestException: No such host is known

我看过其他几个讨论这个问题的问答,但其中许多(例如我链接到的那个)专门在 Azure VM 的上下文中讨论它。他们中的许多人认为这是由 DNS 问题引起的。

不过,我的情况与我读过的其他问答略有不同:当我在 Visual Studio 2019 中通过调试运行我的网站时,它运行得很好。但是,当我在本地发布到 IIS 时,每当我尝试调用 HttpClient 时都会收到此异常。

此外,与我读过的其他一些文章不同,这对我来说不会间歇性发生 - 每次我尝试进行 API 调用时都会发生。

如果这是由其他问答所建议的 DNS 问题引起的,则表明我在本地发布和在 Visual Studio 中进行调试之间肯定存在一些差异。

以下是我配置我的发布的方式(下面的图片摘要供喜欢文字的人使用):

图片摘要:

  • 使用 WebPublishMethod MSDeploy 进行 Web 部署
  • TargetFramework netcoreapp3.1
  • LastUsedBuildConfiguration 版本
  • LastUsedPlatform x86
  • SelfContained 错误
  • MSDeployPublishMethod InProc
  • MSDeployServiceURL 本地主机

其他细节: - 目标网址http://localhost:80 - 正如通常建议的那样,IIS 应用程序池设置为“无托管代码”

此外,无论我如何创建HttpClient 实例,都会发生这种情况,并且代码在调试时工作得很好,所以我认为这更有可能是配置问题而不是代码问题,但值得一提的是,我在Startup 类中使用以下代码来创建它。 (另请参阅here 以供参考)。

       services.AddHttpClient("MyNamedClient", (sp, c) =>
        {
            c.BaseAddress = new Uri("https://api.smartrecruiters.com/");

            c.Timeout = new TimeSpan(4, 0, 0);

            c.DefaultRequestHeaders.Accept.Clear();

            c.DefaultRequestHeaders.Add("Accept", "application/json");

            var ctx = sp.GetService<DatabaseContext>();

            Security security = ctx.Security.First();

            c.DefaultRequestHeaders.Add("APIToken", security.Apikey);
        });

然后,我在需要时使用 ASP.NET Core 的依赖注入来获取 HttpClient 实例。

我还尝试将HttpClient 创建为单例(我知道不是在 ASP.NET Core 应用程序中推荐这样做的方法),但我在使用这种方法时遇到了同样的问题.

这是我尝试使用HttpClient 进行GetAsync 调用时来自事件查看器的完整错误详细信息:

Category: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
EventId: 1
RequestId: 8000000c-0006-ff00-b63f-84710c7967bb
RequestPath: /UsersObject/GetUsersAPICall
SpanId: |f32bc4b9-41d453941179fa9f.
TraceId: f32bc4b9-41d453941179fa9f
ParentId: 

An unhandled exception has occurred while executing the request.

Exception: 
System.Net.Http.HttpRequestException: No such host is known.
 ---> System.Net.Sockets.SocketException (11001): No such host is known.
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at [Namespace].MyHttpClient.GetAsyncWithRetries(HttpClient client, String url) in C:\Users\[Removed]\source\repos\[Removed]\MyhHttpClient.cs:line 54
   at SR_Interaction.Models.SRUser.Search(String emailAddress, HttpClient client) in C:\Users\[Removed]\Models\SRUser.cs:line 100
   at Bosch_Live_Docs.Controllers.UsersObjectController.GetUsersAPICall(String query) in C:\Users\[Removed]\Controllers\UsersObjectController.cs:line 58
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)

有人对我如何解决这个问题有任何建议吗?我认为这可能是我的 IIS 配置或我的发布设置 - 还是我完全走错了轨道?

编辑:根据要求,这是控制器代码:

    [HttpGet]
    [Authorize(Roles = "CreateUser,PatchUser")]
    public async Task<IActionResult> GetUsersAPICall([Bind("query")] [RegularExpression(@"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)$", ErrorMessage = "This does not look like a valid query")] string query)
    {
        if (query == null)
        {
            return BadRequest();
        }
        else if (!ModelState.IsValid)
        {
            // TODO: What to do with this? How do we actually show the validation error?
            return BadRequest("Does not look like a valid query");
        }

        List<SRUser> users = await SRUser.Search(query, clientFactory.CreateClient(Startup.srNamedClient));

        users = users.OrderBy(ur => ur.firstName).ToList();

        if (users.Any())
        {
            return PartialView("_UserList", users);
        }
        else
        {
            return NotFound();
        }
    }

这是我进行实际调用的地方:

public static async Task<List<SRUser>> Search(string emailAddress, HttpClient client)
    {
        string json;

        using (HttpResponseMessage msg = await client.GetAsync("user-api/v201804/users?limit=100&q=" + emailAddress))
        {
            json = await msg.Content.ReadAsStringAsync();
        }

        return JsonSerializer.Deserialize<NextPageContainer<SRUser>>(json).content;
    }

进一步编辑:

这是应用程序池:

这是我安装的模块:

我对这个特定的有点困惑:

是否有必要同时包含两者?当我查看 Ordered 视图时,“旧”视图实际上更高:

但是,我无法重新排序。

这些是问题吗?

进一步编辑:对于本地发布的版本,我发现我的App Pool在内置账户(如ApplicationPoolIdentity)下运行时会出现这个问题。但是,当我使用特定的用户帐户时,它是固定的。但是,这在服务器上不起作用。

【问题讨论】:

  • 发布完整代码,您在哪里拨打电话?要求如何?什么标题?你的控制器怎么样?
  • 你的网站发布后还能用吗?
  • 您的意思是当您从另一个客户端(例如 Postman)调用该服务时,您会得到一个有效的响应,并且您是否已将您的 iis 网站 url 添加到 windows 主机文件中?
  • @Aspram 我可以从多个客户端调用 API - 我有一个 WPF 应用程序和一个控制台应用程序(都是标准的 .NET,但代码在两种情况下都非常相似),用于调用定期结束。我也可以在运行我的网站时通过在 Visual Studio 中调试来调用它。不幸的是,当我发布到 IIS 并以这种方式运行时,我收到了我在问题中提到的错误。
  • 还要确保 IIS 日志也已启用,以便您可以从 IIS 日志文件中查看每个请求的实际情况 - docs.microsoft.com/en-us/iis/manage/…

标签: c# asp.net-core asp.net-core-mvc dotnet-httpclient asp.net-core-3.1


【解决方案1】:

事实证明,请求被公司防火墙阻止。服务器位于两个防火墙后面,这就是为什么更改服务器的入站或出站规则对我没有帮助(因为另一个防火墙只是阻止了呼叫)。

为了解决这个问题,我需要使用代理服务器。我在相应的文档中查找了服务器的完全限定名称。在我的Startup.cs 中,我添加了以下逻辑:

services.AddHttpClient("MyName", c =>
        {
            c.BaseAddress = new Uri("[Vendor API url]");

            c.Timeout = new TimeSpan(4, 0, 0);

            c.DefaultRequestHeaders.Accept.Clear();

            c.DefaultRequestHeaders.Add("Accept", "application/json");

            c.DefaultRequestHeaders.Add("ApiToken", RetrieveApiKey());
        })
            .ConfigurePrimaryHttpMessageHandler(() =>
            {
                return new HttpClientHandler()
                {
                    AllowAutoRedirect = true,
                    SslProtocols = SslProtocols.Tls13,
                    UseProxy = true,
                    Proxy = new WebProxy("ProxyServerName", 8080)
                    {
                        // The proxy server allows NTLM and Kerberos authentication
                        UseDefaultCredentials = true
                    }
                };
            });

【讨论】:

    猜你喜欢
    • 2011-06-25
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 2021-03-20
    相关资源
    最近更新 更多