【问题标题】:Requests to third party API from .NET Core app timeout in IISIIS 中 .NET Core 应用程序对第​​三方 API 的请求超时
【发布时间】:2021-06-07 11:27:47
【问题描述】:

我有一个在 IIS 中运行的 .NET Core Web API 应用程序,它可以接收和响应请求,但它需要向第三方 API (Twilio) 发出请求。这些请求在本地托管时成功,但在 IIS 中托管时会超时。

.NET Core Web API 应用程序面向 v2.1 并在 Windows Server 和 IIS 7 上运行。我按照this article 中的指南为该站点设置了一个专用应用程序池。

应用程序池设置:

我正在使用 Postman 向应用发出 GET 和 POST 请求。

对测试控制器的 GET 和 POST 请求工作正常。我对这些测试端点所做的只是返回接收到的参数。

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    [HttpGet]
    public string Get(int id)
    {
        return $"response to GET; id:{id}";
    }

    [HttpPost]
    public string Post([FromBody] int id)
    {
        return $"response to POST; foo:{id}";
    }
}

上述端点使用 IISExpress 在 VS2019 中本地运行调试模式,并且在部署到 Web 服务器并使用 IIS7 托管时也可以工作。

当我尝试调用第三方 API (Twilio) 时,问题就开始了。当应用程序在本地运行时,这些调用再次成功。几乎没有延迟。我发布到 SMSController 的 post 端点,请求被触发,我在几秒钟内收到一条短信。但是,从 Web 服务器和 IIS 到这些端点的 GET 和 POST 请求失败。

[Route("api/[controller]")]
[ApiController]
public class SMSController : ControllerBase
{
    private string twilioSID = "xxxxxx";
    private string twilioAuthToken = "xxxxxx";
    private string twilioPhoneNumber = "+15555555555";

    [HttpGet]
    public string Get(string phoneNumber)
    {
        TwilioClient.Init(twilioSID, twilioAuthToken);

        var message = MessageResource.Create(
            body: $"TEST message via Twilio",
            from: new Twilio.Types.PhoneNumber(twilioPhoneNumber),
            to: new Twilio.Types.PhoneNumber(phoneNumber)
        );

        return message.Status.ToString();
    }

    [HttpPost]
    public string Post([FromBody] GeoEvent geoEvent)
    {
        TwilioClient.Init(twilioSID, twilioAuthToken);

        var message = MessageResource.Create(
            body: $"TEST message via Twilio",
            from: new Twilio.Types.PhoneNumber(twilioPhoneNumber),
            to: new Twilio.Types.PhoneNumber(geoEvent.PhoneNumber)
        );

        return message.Status.ToString();
    }
}

当托管在 IIS 中时,对上述端点的 GET 和 POST 请求会得到 500 响应。抛出以下异常:

System.Net.Http.HttpRequestException: 连接尝试失败,因为连接方在一段时间后没有正确响应,或建立连接失败,因为连接的主机没有响应---> System.Net.Sockets。 SocketException: 连接尝试失败,因为连接方一段时间后没有正确响应,或者连接的主机没有响应,建立连接失败

最后,这是我在 VS2019 中发布应用程序时 SDK 为我生成的 web.config。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\TwilioService.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
    </system.webServer>
  </location>
</configuration>

我的本​​地计算机和运行 IIS 的 Web 服务器都没有位于公司代理之后。

我是否缺少允许 .NET Core 通过 IIS 向第三方发出请求的 IIS 或 web.config 设置?

更新: 我现在在运行 Windows Server 2016 的不同 Web 服务器上重现了相同的问题。这台机器设置有 .NET 5、IIS 10 和 .NET 5 的托管包。我还安装了 VS2019 并重新创建了要运行的 Web api 项目服务器本地。结果如下:

  • 在IIS Express本地运行,api控制器可以成功 向 Twilio api 发出请求并获得响应。短信 消息发送成功。没有错误。
  • 在 IIS 10 中本地运行,api 控制器调用 Twilio 但 未能得到回应。出现以下错误:

Twilio.Exceptions.ApiConnectionException:连接错误:POSThttps://api.twilio.com/2010-04-01/Accounts//Messages.json ---> System.Net.Http.HttpRequestException: 连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应。 (api.twilio.com:443)

重申一下,以上两种情况都在同一台机器上运行。唯一的区别是 IIS Express 与 IIS 10。这是 SSL 证书问题吗?由于 IIS 10 用作 .NET 核心应用程序的反向代理,因此通过 IIS 从 .NET 核心应用程序识别或转发证书是否会出现问题?

【问题讨论】:

    标签: iis .net-core request


    【解决方案1】:

    尝试从您的机器命令提示符 ping 第三方服务 URL。

    确保防火墙端口设置为允许。检查防病毒软件是否正在阻止连接。

    尝试将 defaultProxy 部分添加到我的 web.config 以使我的网站连接到 Web 服务。

    https://docs.microsoft.com/en-US/troubleshoot/dotnet/framework/cannot-consume-web-service-via-http-proxy

    【讨论】:

    • 我尝试从两台机器上 ping api.twilio.com。有趣的是,即使从我的本地机器对 twilio 的 api 调用成功,它也失败了。使用 Fiddler 我注意到了一些东西。当我的本地机器上运行的 api 通过 http 调用 twilio 时,会自动调用 api 的 https 端口。在 Startup.cs 我有 app.UseHttpsRedirection()。所以在本地运行 api 这是可行的。但是,在 Web 服务器上,不会自动调用 https。我必须缺少一个配置设置才能在带有 .net core 2.1 的 IIS 中工作
    【解决方案2】:

    已解决。毕竟是公司代理。我有不好的信息表明 Web 服务器不在代理后面,但它确实在后面。 Twilio 在他们的文档中为这种确切的场景提供了一个解决方案,涉及使用自定义代理休息客户端类。它是 System.Net.HttpClient 的包装器。该服务现在可以使用设置了代理服务器 url 的此类通过代理调用 Twilio。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2021-01-11
      相关资源
      最近更新 更多