Array ( [url] =\> https://bildpfad.de/img/products/00/149289 . jpg ) {"errors":[{"status":"500","code":"CONTENT\_\_MEDIA\_UPLOAD","title":"Internal Server Error","detail":"You must provide a valid url.","meta":{"parameters":{"message":"You must provide a valid url."}}}]}
ich weiß ja nicht wir du den Payload überträgst, es sieht mir aber danach aus, als ob der Parameter nicht per POST-Body mitgeschickt wird.
Sonst müsstest du mal schauen, wie dein Request bei dem MediaUploadController in der upload-Action ankommt.
Hey,
Hier mal meine Erfahrungen mit den Vorgestellten Lösungen:
Die Lösung von canetti2klappt nur für URLs die Außerhalb des eigenen privaten Netzwerkes liegen. Uploads von Servern mit IP-Adressen wie 192.168.XXX.XXX oder 10.0.XX.XXX werden mit der Fehlercode: CONTENT__MEDIA_ILLEGAL_URL abgewießen. Das ganze passiert aufgrund der Klasse
FileUrlValidator, welche die angegebenen URLs prüft.
Dazu mal eine Frage: Gibt es eine Möglichkeit um Bilder per API von lokalen URLs hochzuladen? Wenn nicht, sei mir bitte folgende naive Frage gestattet: Warum nicht?
Für alle die Bilder von ihrem lokalen Filesystem mithilfe der API hochladen wollen gibt es folgende Möglichkeit:
Als Response erhält man dann die neu erzeugte media-ID
Unter Angabe der neuen media-ID ein zweiter POST an /api/v2/_action/media/media-ID/upload?extension=jpg&fileName=bildname
mit Content-Type: image/jpeg und als Payload die binären Daten des Bildes.
CURL-Beispiel:
ich kenne C# nicht wirklich… aber kann es sein, dass du statt “Path.GetFileName(pFileName)” eher “path.getfilenamewithoutextension(pFileName)” übergeben musst ?
Bei fileName wird der Dateiname ohne Endung erwartet.
Allerdings war es das leider nicht.
Auch mit einer anderen Datei oder einer .png klappt es nicht.
Alle meine Test Dateien sind weniger als 150KB groß. An der Größe sollte es auch nicht liegen.
Als Fehlermeldung erhalte ich immer: ‚Unsupported Media Type‘ detail: ‚All provided media types are unsupported.‘
Hier noch mal mein C# Code für den Punkt 2):
byte myImageData = null;
using (System.IO.FileStream myFS = System.IO.File.Open(pFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
myImageData = new byte[myFS.Length];
myFS.Read(myImageData, 0, (int)myFS.Length);
myFS.Close();
}
var requestContent = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(myImageData);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse(„image/jpeg“);
requestContent.Add(imageContent, „image“, Path.GetFileName(pFileName));
using (var myClient = new HttpClient())
{
myClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(„Bearer“, gBearerKey.Replace(’"’, ’ ').Trim());
myClient.BaseAddress = new Uri(gShopMainUrl);
Wirf doch mal Wireshark an und vergleiche den funktionierenden Aufruf mit dem nicht funktionierenden…
Danke für den Tipp mit Wireshark. Ich habe es mal ausprobiert und den curt-Request sowie den Request aus meinem Script aufgezeichnet. Leider verstehe ich zu wenig von den Protokollen und verstehe es nicht ganz. Was mir auffällt ist, dass der „Frame“ aus curl wesentlich mehr Bytes beinhaltet als der „Frame“ aus dem Request meines Scripts.
Request aus curl (Bild wird erfolgreich zu Shopware übertragen)
path = "api/v1/_action/media/" + media.Id + "/upload?";
path += "extension=" + HttpUtility.UrlEncode(mediaUpload.Extension);
path += "&fileName=" + HttpUtility.UrlEncode(mediaUpload.Filename);
RestRequest requestUpload = new RestRequest(path, Method.POST);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/vnd.api+json"));
httpClient.DefaultRequestHeaders.Add("Authorization", this.AuthHeader);
byte[] rawBytes = File.ReadAllBytes(filepath);
ByteArrayContent byteArrayContent = new ByteArrayContent(rawBytes);
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("image/" + mediaUpload.Extension.ToLower());
byteArrayContent.Headers.ContentLength = rawBytes.LongLength;
var result = httpClient.PostAsync(this._config.server + "/" + path, byteArrayContent).Result;
}
Oben der Code; ist so nicht ausführbar sollte aber in etwa das Prinzip zeigen. Letztlich wird das Image als binary gesendet. mediaUpload ist eine eigene Class.
Ich habe es nun auch geschafft. Ich lade die Bilder aus einer MS Access-Applikation hoch und habe dafür eine Komponente der Chilkat-API verwendet. Ich bin kein Protokollexperte, was ich aber herausgefunden habe ist, dass diese die Bilderdaten über TCP versendet. Curl dagegen packt alles in das HTTP-Paket.
Ich habe nun MSXML2.ServerXMLHTTP in Access verwendet und damit klappt es! Auch hier werden die Daten ins HTTP-Paket gepackt und damit läuft es.
RestRequest requestUpload = new RestRequest(path, Method.POST);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue(„application/vnd.api+json“));
byte rawBytes = File.ReadAllBytes(filepath);
ByteArrayContent byteArrayContent = new ByteArrayContent(rawBytes);
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue(„image/“ + mediaUpload.Extension.ToLower());
byteArrayContent.Headers.ContentLength = rawBytes.LongLength;
var result = httpClient.PostAsync(this._config.server + „/“ + path, byteArrayContent).Result;
}
Oben der Code; ist so nicht ausführbar sollte aber in etwa das Prinzip zeigen. Letztlich wird das Image als binary gesendet. mediaUpload ist eine eigene Class.