Bur*_*ort 1 c# asp.net-web-api
我有一个简单的 web api,它获取一个 url,并生成一个短数字作为短 url。我创建了一个 VS 控制台应用程序,我在其中通过HTTPClient对象调用 web api 。当我第一次运行代码时,它抛出以下错误:
错误消息: 发生了一个或多个错误。
内部异常: System.Net.Http.HttpRequestException:发送请求时出错。---> System.Net.WebException: 基础连接已关闭:发送时发生意外错误。---> System.IO.IOException: 无法从传输连接读取数据:远程主机强行关闭了现有连接。---> System.Net.Sockets.SocketException: 远程主机在 System.Net.Sockets.Sockets.Socket.EndReceive(IAsyncResult asyncResult) 处的 System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) 处强行关闭了现有连接--- 内部异常堆栈跟踪结束 --- 在 System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) 在 System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) --- 内部异常堆栈跟踪结束 --- 在 System .Net.HttpWebRequest。
这是我用来调用 web api 的代码。通过浏览器调用 web api 工作得很好。
static void Main(string[] args)
{
string url = "https://app1/api/AddUrl?longUrl=http://google.com";
var result = GetTinyUrl(url).Result;
Console.WriteLine(result.ShortUrl);
}
protected static async Task<UrlResponse> GetUrl(string baseUrl)
{
HttpClientHandler handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
var client = new HttpClient(handler);
var response = client.GetAsync(baseUrl).Result;
if (response.IsSuccessStatusCode)
{
HttpResponseMessage response1 = response;
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<UrlResponse>(resp);
return result;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*xon 12
只是说,在连接到我正在编写的天蓝色服务时,我花了几个小时研究类似的问题。
无法弄清楚为什么邮递员工作正常但我的代码却严重失败。同样,我在代码中尝试过的其他 URL 工作正常或出现预期的失败。
最后失败的原因是我忘记降低TLS/SSL 设置刀片中的最低 TLS 版本!
我认为旧版本的 HttpClient 只能处理 TLS v1.0。
将.Result阻塞调用与异步等待混合使用可能会导致死锁。
如果使用 async await 然后一直使用 async,并避免HttpClient为每个调用创建一个新的实例,因为这会导致 socked 耗尽。
static Lazy<HttpClient> http = new Lazy<HttpClient>(() => {
//Handle TLS protocols
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Tls
| System.Net.SecurityProtocolType.Tls11
| System.Net.SecurityProtocolType.Tls12;
var handler = new HttpClientHandler() {
UseDefaultCredentials = true
};
var client = new HttpClient(handler);
return client;
});
protected static async Task<UrlResponse> GetUrl(string baseUrl) {
var client = http.Value;
var response = await client.GetAsync(baseUrl); //Remove .Result and just await
if (response.IsSuccessStatusCode) {
HttpResponseMessage response1 = response;
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<UrlResponse>(resp);
return result;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
由于这是一个控制台应用程序并且只有一个线程然后调用异步,因此您必须更改在 main 中调用异步方法的方式
static void Main(string[] args) {
string url = "https://app1/api/AddUrl?longUrl=http://google.com";
var result = GetTinyUrl(url).GetAwaiter().GetResult(); //<--
Console.WriteLine(result.ShortUrl);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8268 次 |
| 最近记录: |