Vor einiger Zeit habe ich Code implementiert, um eine REST Api mit der Klasse HttpClient
zu konsumieren.HttpRequestException - Ist das ein Client- oder Serverproblem?
using (var client = new HttpClient() { BaseAddress = new Uri(@"https://thirdparty.com") })
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(...);
var uri = new Uri(@"rest/api/foo", UriKind.Relative);
var content = new StringContent(json.ToString());
using (var response = await client.PostAsync(uri, content))
{
// etc ...
}
}
Dieser Code schien völlig in Ordnung, sowohl gegen die Test- und Produktionsumgebungen (von denen jeder eine Test/Produktion uri Zugriff) zu arbeiten. Vor kurzem haben wir begonnen, nur eine HttpRequestException in der Produktionsumgebung zu erhalten: System.Net.Http.HttpRequestException: Error while copying content to a stream.
Das ist ein bisschen seltsam schien, so habe ich Postman die gleiche Botschaft senden und es funktionierte gut. Ich war mir nicht sicher, warum unser Code versagte und Postman arbeitete. Ich habe einen Parameter in den JSON-Daten (der Status von "NY" zu "NV") geändert und unser .NET-Code hat gut funktioniert - natürlich können wir nicht einfach die falschen JSON-Daten senden, also ist dies keine Lösung; Dies war eher eine Beobachtung, dass der exakt gleiche Code mit unterschiedlichen Inhalten funktionierte.
Interessant ist, dass wir zwei Codeänderungen vornehmen können, die das beheben werden. Erstens kann Postman mit dem RestSharp
Paket einen funktionierenden C# -Code generieren. Alternativ fand ich eine answer von einer anderen Frage zeigt auf mit HttpVersion 1,0:
using (var request = new HttpRequestMessage(HttpMethod.Post, uri))
{
request.Version = HttpVersion.Version10;
request.Content = new StringContent(json.ToString());
using (var response = await client.SendAsync(request))
{
// etc ...
}
}
Das verwirrende Teil ist, dass Postman die HTTP/1.1-Version verwendet. Also, in Zusammenfassung:
Warum in aller Welt ist Postman in der Lage, mit HTTP/1.1 zu arbeiten, aber HttpClient schlägt fehl? Ist das ein Problem mit unserem Kunden (der Code funktioniert für andere US-Staaten)? Ist das ein Fehler in .NET Framework? Ist etwas falsch mit der Implementierung/Hosting der REST Api von der dritten Partei?
Postman Header:
POST rest/api/foo HTTP/1.1
Host: thirdparty.com
Content-Type: application/json
Authorization: Basic SOME_ENCRYPTED_USER_PASS
Cache-Control: no-cache
Postman-Token: 2fa5b5a0-b5d3-bd4c-40f0-d2b55b60316b
Probe Json:
{
"stateCode": "NY",
"packageID": "58330",
"name": "58330-PRI-1",
"documents": [
{
"type": "SPECIAL",
"name": "Sample Document",
"documentID": "3569976"
}
],
"descriptions": [
{
"city": "New York",
"state": "NY"
}
]
}
Stacktrace:
AggregateException: One or more errors occured.
HttpRequestException: Error while copying content to a stream.
IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
SocketException: An existing connection was forcibly closed by the remote host.
Ist der Text des Postboten genau so wie der mit client.PostAsync() gesendete Text? Ich glaube, der Unterschied zwischen den Versionen ist der Keep-Alive-Header, so dass es möglich sein könnte, dass Postman Timeouts anders behandelt als .NET. –
@NickSpicer: Richtig, der Körper ist die gleichen JSON-Daten. Und ich glaube, es ist die Tatsache, dass es HTTP/1.1 vs HTTP/1.0 ist, die die Verbindung keep-alive vs close bestimmt. Ich habe meine Antwort aktualisiert, um die Briefkopfdaten hinzuzufügen. –
Haben Sie die Details der HttpRequestException verfolgt? –