C# 从ASP.net 4 Web API 2项目通过HttpClient调用REST服务会导致异常

C# 从ASP.net 4 Web API 2项目通过HttpClient调用REST服务会导致异常,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,当前情况:我使用WebAPI 2模板创建了一个ASP.net项目(web项目)。其中一个HTTPGET方法现在尝试使用以下代码向另一个restapi发出请求 [HttpGet] public string Get() { var uri = @"http://api.../..."; var httpClient = new HttpClient(); var response = httpClient.GetAsync(uri).GetAwaiter().GetRes

当前情况:我使用WebAPI 2模板创建了一个ASP.net项目(web项目)。其中一个HTTPGET方法现在尝试使用以下代码向另一个restapi发出请求

[HttpGet]
public string Get()
{
    var uri = @"http://api.../...";

    var httpClient = new HttpClient();
    var response = httpClient.GetAsync(uri).GetAwaiter().GetResult(); // <- exception here

    response.EnsureSuccessStatusCode();

    string content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

    return content;
}
到目前为止我所尝试的:

  • 我在浏览器中使用了完全相同的URI(通过复制和粘贴),并返回带有一些数据的JSON
  • 在创建WebAPI2项目之前,我与ASP.NET5的RC候选者打过交道。我创建了一个基于ASP.NET5模板“WebAPI”的项目。在那里,我有完全相同的代码,它工作得很好
  • 假设:我的假设是,ASP.net 4 Web API 2模板中的配置有一些阻止获得响应的配置。我发现了一些类似的问题,似乎有些私人网络被禁用了


    问题:在基于ASP.net 4 Web API 2的项目中使用HttpClient时,什么会阻止收到响应?

    我找到了根本原因。简而言之,ASP.net 5模板使用了一个代理,可能是通过Windows组策略配置的代理,而ASP.net 4模板直接连接到其他REST服务。但由于某些防火墙禁止这样做,所以它不起作用

    详细回答:为了检查两个模板(ASP.net 4和5)的网络流量,我使用了sysinternals工具中的Process Monitor。我将过滤器设置为IISExpress.exe和dnx.exe

    对于ASP.net 4模板,如下所示

    只有两个条目可以看到IISExpress直接连接到REST服务。在ASP.net 5中,有更多的条目,因为它使用代理而不是直接连接。我实际上假设这是一个代理,因为它的主机名。这里需要注意的一点是,dnx.exe正在建立连接,而不是IISExpress.exe

    为了让IISExpress为ASP.NET4模板使用代理,我在projects
    web.config
    中添加了以下行。我使用了进程监视器中显示的主机名和端口

    <system.net>
      <defaultProxy>
        <proxy usesystemdefault="True"
               proxyaddress="http://proxy.<hostname>:<port>"
               bypassonlocal="True"/>
      </defaultProxy>
    </system.net>
    
    
    

    因此,我的假设是,在Windows中的某个位置配置了此代理,可能是通过组策略(?)。Firefox、dnx.exe和其他人正在使用此配置。但是IISExpress忽略了这一点,因此没有收到RESTAPI的答复。

    可能是他不允许公众使用,可能是允许某些特定的域。就像我觉得的那样

    为了更好地理解,您可以阅读本文:

    您可以尝试使用其他get方法,如
    GetStringAsync(String)
    ?结果完全相同
    <system.net>
      <defaultProxy>
        <proxy usesystemdefault="True"
               proxyaddress="http://proxy.<hostname>:<port>"
               bypassonlocal="True"/>
      </defaultProxy>
    </system.net>