从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常
Posted
技术标签:
【中文标题】从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常【英文标题】:Calling REST service via HttpClient from ASP.net 4 Web API 2 project results in exception 【发布时间】:2016-08-07 05:57:41 【问题描述】:现状:我使用 WebAPI 2 模板创建了一个 ASP.net 项目(网络项目)。现在,其中一个 HTTPGET 方法尝试使用以下代码向另一个 REST API 发出请求。
[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;
在标有注释的行中,抛出以下带有“无法连接到远程服务器”消息的HttpRequestException
(内部异常)。
System.Net.Http.HttpRequestException was unhandled by user code
HResult=-2146233088
Message=An error occurred while sending the request.
Source=mscorlib
...
InnerException:
HResult=-2146233079
Message=Unable to connect to the remote server
Source=System
StackTrace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
InnerException:
ErrorCode=10060
HResult=-2147467259
Message=A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond ...
NativeErrorCode=10060
Source=System
StackTrace:
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
InnerException:
到目前为止我尝试了什么:
-
我在浏览器中使用了完全相同的 URI(通过复制和粘贴),并返回了带有一些数据的 JSON。
在创建 WebAPI2 项目之前,我使用了 ASP.net 5 的 RC 候选对象。我基于 ASP.net 5 模板“Web API”创建了一个项目。我有完全相同的代码,并且运行良好。
假设: 我的假设是 ASP.net 4 Web API 2 模板中的配置有一些配置阻止了响应。我在 SO 上发现了一些类似的question,似乎某些私有网络已被禁用。
问题:在基于 ASP.net 4 Web API 2 的项目中使用 HttpClient 时,什么会阻止接收响应?
【问题讨论】:
你能试试其他的get方法比如GetStringAsync(String)
吗?
完全一样的结果
【参考方案1】:
这可能是他没有允许 Public 使用,可能有一些特定的域被允许。在我看来。
您可以阅读这篇文章以获得更好的理解: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
【讨论】:
【参考方案2】:我能够找出根本原因是什么。简短的回答是 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.net 4 模板的代理,我在项目 web.config
中添加了以下几行。我使用了进程监视器中显示的主机名和端口。
<system.net>
<defaultProxy>
<proxy usesystemdefault="True"
proxyaddress="http://proxy.<hostname>:<port>"
bypassonlocal="True"/>
</defaultProxy>
</system.net>
所以我的假设是在 Windows 的某个地方配置了这个代理,可能是通过组策略(?)。 Firefox、dnx.exe 和其他人正在使用此配置。但是 IISExpress 忽略了这一点,因此没有收到来自 REST API 的答复。
【讨论】:
以上是关于从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ASP.NET web api 3 项目在 ASP.NET web api 2 执行时没有请求就无法启动?
ASP.NET MVC 4 / MVVM / Web API 的良好结构? [关闭]
Asp.Net Web API 2第三课——.NET客户端调用Web API
ASP.Net MVC 4 Web API 控制器不适用于 Unity.WebApi
前端 ASP.NET MVC4 作为一个项目,ASP.NET Web API 作为同一解决方案中的另一个项目 - 如何从前端调用 WebAPI?