Je travaille sur une intégration avec Alternative Payments en utilisant leur intégration de pages hébergées . Leur SDK C# n'a pas cette intégration disponible pour le moment, mais comme vous pouvez le voir c'est assez simple et j'ai fait une petite classe pour envoyer la requête post et obtenir la réponse JSON.
J'ai testé l'objet json que j'envoie sur PostMan et cURL et les deux fonctionnent, ainsi que l'en-tête d'authentification, donc je pense qu'ils ne sont pas le problème. Voici le constructeur de ma classe :
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);
}
Et la méthode où j'enregistre les données :
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 "";
}
Puis j'obtiens cette erreur : An existing connection was forcibly closed by the remote host
à la ligne PostAsync. Voici les détails de l'erreur :
[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.]
J'utilise C# 4.5, Asp.Net MVC. J'ai lu des réponses pour la même erreur et aucune d'entre elles n'a résolu mon problème jusqu'à présent. Que me manque-t-il dans ce code ?
Merci pour toute aide
0 votes
Que voyez-vous, le cas échéant, dans la réponse de Fiddler ?
12 votes
Juste un bon conseil, en utilisant
var
pour tout fera que vos collègues vous détesteront. N'utilisezvar
lorsque le type est apparent (c'est-à-direvar date = new DateTime();
) son très clairement unDateTime
. Cependantvar response = _httpClient.PostAsync(this._baseUrl + "/transactions/hosted", content).Result;
est pas clair parce que.Result
est une propriété et non un type implicite.19 votes
@maccettura au contraire, en utilisant
var
rend le code beaucoup plus propre. Il n'y a pas d'ambiguïté sur le type, sauf si vous écrivez des méthodes très longues, auquel cas vous devez vraiment, vraiment les séparer. Les collègues de travail vous détesteront si vous écrivez des méthodes si longues qu'ils ne peuvent pas voir quels sont les types.4 votes
@PanagiotisKanavos
var
ne rend le code plus propre que lorsque le type est implicite en utilisantvar
partout (même dans les cas où le type n'est pas implicite) est simplement mauvaise programmation .8 votes
@maccettura quant à
.Result
les collègues détesteront toute personne qui bloque un appel asynchrone avec.Wait()
ou.Result
. Le type de retour est de toute façon connu. Il s'agit de HttpResponseMessage. Voir le nom ne vous aidera pas car vous devrez de toute façon utiliser intellisense pour trouver les méthodes à utiliser.4 votes
@maccettura ce qui, par exemple, est la raison pour laquelle les langages fonctionnels utilisent l'inférence de type au lieu de spécifier le type explicitement Vous n'êtes peut-être pas familier avec inférence de type. Cela n'en fait pas une mauvaise programmation. D'un autre côté, un appel à
.Result
devrait susciter l'inquiétude de quiconque1 votes
@PanagiotisKanavos c'est ça. vraiment connu ? Sans tenir compte d'une expérience préalable dans une bibliothèque de .NET, quel est le moyen le plus simple pour moi de connaître le type (en le déclarant dans les cas où c'est le cas) ? pas de sous-entendus redondants .
1 votes
@PanagiotisKanavos et oui, je suis d'accord que l'OP ne devrait pas bloquer les appels asynchrones (si ce n'était pas déjà connu, le code que j'ai posté est directement issu de la question de l'OP et non du mien).
2 votes
Complètement à côté de la plaque. Je ne sais pas quelle IDe vous utilisez, j'utilise Visual Studio et lorsque vous survolez la variable, elle vous indique le type. Merci
1 votes
Duplicata possible de Une connexion existante a été fermée de force par l'hôte distant.