【发布时间】:2017-09-14 15:29:25
【问题描述】:
我正在使用他们的hosted page integration 与 Alternative Payments 进行集成。他们的 C# SDK 目前没有这种集成,但正如您所见,它非常简单,我创建了一个小类来发送 post 请求并获取 JSON 响应。
我测试了我在 PostMan 和 cURL 上发送的 json 对象,它们都可以工作,还有身份验证标头,所以我认为它们不是问题。这是我的类的构造函数:
public AlternativePaymentsCli(string apiSecretKey)
{
this._apiSecretKey = apiSecretKey;
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var authInfo = _apiSecretKey;
authInfo = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:", _apiSecretKey)));
// The two line below because I saw in an answer on stackoverflow.
_httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
_httpClient.DefaultRequestHeaders.Add("Keep-Alive", "3600");
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Anything.com custom client v1.0");
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);
}
以及我发布数据的方法:
public string CreateHostedPageTransaction(HostedPageRequest req)
{
var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
// I send this same json content on PostMan and it works. The json is not the problem
var content = new StringContent(JsonConvert.SerializeObject(req, settings), Encoding.UTF8, "application/json");
var response = _httpClient.PostAsync(this._baseUrl + "/transactions/hosted", content).Result;
var responseText = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
if (response.IsSuccessStatusCode)
return responseText;
return "";
}
然后我在 PostAsync 行收到此错误:An existing connection was forcibly closed by the remote host。这是错误详情:
[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) +8192811
System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) +47
[IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.]
System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) +294
System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) +149
[WebException: The underlying connection was closed: An unexpected error occurred on a send.]
System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) +324
System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) +137
[HttpRequestException: An error occurred while sending the request.]
我正在使用 C# 4.5,Asp.Net MVC。我一直在阅读相同错误的答案,但到目前为止,他们都没有解决我的问题。我在这段代码中遗漏了什么?
感谢您的帮助
【问题讨论】:
-
只是一个很好的提示,使用
var做任何事情都会让你的同事讨厌你。仅当类型明显(即var date = new DateTime();)时才使用var,其非常显然是DateTime。但是var response = _httpClient.PostAsync(this._baseUrl + "/transactions/hosted", content).Result;不清楚,因为.Result是一个属性,而不是隐含它是什么类型。 -
@maccettura 相反,使用
var使代码更清晰。除非您编写非常长的方法,否则类型是什么是没有歧义的,在这种情况下,您应该真的,真的将它们分开。如果你编写的方法太长以至于看不到类型是什么,同事会讨厌你 -
@PanagiotisKanavos
var仅在 隐含类型 时使代码更清晰,在任何地方使用var(即使在不隐含类型的情况下)只是 糟糕的编程. -
@maccettura 至于
.Result,同事会讨厌任何用.Wait()或.Result阻止异步调用的人。无论如何,返回类型是已知的。它是 HttpResponseMessage。看到名称对您没有帮助,因为无论如何您都必须使用智能感知来查找要使用的方法 -
@maccettura 例如,这就是为什么函数式语言使用类型推断而不是明确指定类型的原因 你可能不熟悉类型推断。这并没有使它成为糟糕的编程。另一方面,打电话给
.Result应该引起任何人的不满
标签: c# asp.net json dotnet-httpclient