Ich habe ein Problem, wenn ich einen HTTP-POST über HttpClient
ausführen. Ich benutzte es, Firmware ESP8266 Arduino OTA Firmware-Upgrade-Schnittstelle laden (siehe Beispiel: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/examples), aber es löst eine Ausnahme zu sagenC# - Unbekannte Antwort beim Ausführen von HTTP POST über HttpClient?
"WinHttpException: Der Server eine ungültige oder unbekannte Antwort zurückgegeben"
Wenn ich das Firmware-image von cURL hochladen, es mit dem Befehl total gut funktioniert unter:
curl -F "[email protected]" 192.168.1.104/update
ich das Debuggen mit Fiddler versucht habe, sagte er mir, dass ich habe 504 Gateway Timeout. Aber es wird nicht passieren, wenn ich cURL verwende.
Ich denke, es könnte durch einige Fehler innerhalb der Firmware OTA Update API ESP8266 verursacht werden, und mein Programm hat keine Kopfzeile generiert, die die API "erfüllen" kann, so wurde es irgendwie abgelehnt. Wenn möglich, möchte ich fragen, ob es eine Problemumgehung für dieses Problem gibt? Danke im Voraus!
Hier ist die von Fiddler erfasst Rohresultat der Curl:
POST http://192.168.1.104/update HTTP/1.1
Host: 192.168.1.104
User-Agent: curl/7.51.0
Accept: */*
Connection: Keep-Alive
Content-Length: 335869
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------32e3208a349a700d
--------------------------32e3208a349a700d
Content-Disposition: form-data; name="image"; filename="firmware.bin"
Content-Type: application/octet-stream
.......(Firmware File Content).......
Hier mein Programm des Rohresultat ist:
POST http://192.168.1.104/update HTTP/1.1
Connection: Keep-Alive
Content-Type: multipart/form-data; boundary="----TwilightFirmware"
Accept-Encoding: gzip, deflate
Content-Length: 335857
Host: 192.168.1.104
------TwilightFirmware
Content-Type: application/octet-stream
Content-Disposition: form-data; name=update; filename=firmware.bin; filename*=utf-8''firmware.bin
.............(Firmware file Content)...........
Hier ist mein (Teil) C# -Code,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Http;
using System.Diagnostics;
namespace JasmineApp.Core
{
class LocalFirmwareUpdater
{
public async Task<bool> UploadLocalFirmware(string baseUrl, string filePath)
{
Debug.WriteLine("[Core.FirmwareUpdater] Base URL is: " + baseUrl);
HttpCommandHandler httpHandler = new HttpCommandHandler();
httpHandler.SetHttpBaseUrl(baseUrl);
byte[] firmwareContent = File.ReadAllBytes(filePath);
// HttpContent postContent = new StreamContent(firmwareStream);
HttpContent postContent = new ByteArrayContent(firmwareContent);
postContent.Headers.Add("Content-Type", "application/octet-stream");
var formData = new MultipartFormDataContent("----TwilightFirmware");
formData.Add(postContent, "update", "firmware.bin");
string result = await httpHandler.ExecutePostAsync("/update", formData);
// string result = await httpHandler.ExecutePostAsync("/update", postContent);
return (
result.Equals(string.Empty)
|| result == null
|| result.Contains("Fail")) ? false : true;
}
}
}
... und HTTP-Handler-Code ist hier:
public async Task<string> ExecutePostAsync(string pathAndQuery, MultipartFormDataContent content)
{
Debug.WriteLine("[Core.HttpHandler] Request POST URL: " + BaseUrl + pathAndQuery);
using(var client = this.getHttpClient())
{
client.Timeout = TimeSpan.FromSeconds(2000000);
var httpResponseMessage = client.PostAsync(pathAndQuery, content).Result;
if(httpResponseMessage != null)
{
string responseResult = await httpResponseMessage.Content.ReadAsStringAsync();
Debug.WriteLine("[Core.HttpCommandHandler] POST return message: " + httpResponseMessage.Content.ReadAsStringAsync().Result);
return responseResult;
}
else
{
// Return an empty string to avoid exceptions
// Don't need to worrry if it's empty.
return string.Empty;
}
}
Übrigens können Sie bei Bedarf nach meinem vollständigen Code auf GitHub suchen. Hier ist der Link: https://github.com/huming2207/JasmineApp.Windows
Ich habe versucht, es zu benutzen vorher, bleibt eigentlich immer noch gleich –