AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke MultipartFormData und TRESTRequest
Thema durchsuchen
Ansicht
Themen-Optionen

MultipartFormData und TRESTRequest

Ein Thema von Rabenrecht · begonnen am 20. Okt 2022 · letzter Beitrag vom 27. Okt 2022
Antwort Antwort
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#1

AW: MultipartFormData und TRESTRequest

  Alt 26. Okt 2022, 16:52
In dem Fall solltest du mal ein Beispiel geben, wie der Request genau aussehen soll, was du aktuell raus bekommst und wie du das gemacht hast.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Rabenrecht

Registriert seit: 9. Dez 2016
79 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: MultipartFormData und TRESTRequest

  Alt 27. Okt 2022, 07:30
Ok

Soll:
Code:
POST /api/derEndpunkt?QueryParameter=1234 HTTP/1.1
Connection: Keep-Alive
Content-Type: multipart/form-data; boundary=--------102722082331395
Accept: application/json, application/*+json
Accept-Charset: UTF-8, *;q=0.8
Authorization: Basic cm9vdDpvcHRpbWFs
Cookie: JSESSIONID=CACA72D331F84414ADF4E7C8CFFE02C2
User-Agent: Embarcadero RESTClient/1.0
Content-Length: 9121
Host: zielhost

----------102722082331395
Content-Disposition: form-data; name="nameJson"
Content-Type: application/json
Content-Transfer-Encoding: quoted-printable

{"key":"value"}
----------102722082331395
Content-Disposition: form-data; name="nameFile"; filename="Test_Bild.png"
Content-Type: image/png
Content-Transfer-Encoding: binary

[das serialisierte Bild]
----------102722082331395--

Was ich mache:
Delphi-Quellcode:
procedure PostObject;
begin
  FRestRequest.Params.Clear;
  FRestRequest.ClearBody;
  FRestRequest.Response.ResetToDefaults;
  FRestRequest.Method := rmPOST;
  FRestRequest.Resource := '/api/derEndpunkt?QueryParameter=1234';

  //Variante 1
  //FRestRequest.AddParameter('nameJson', '{"key":"value"}', false);

  //Variante 2
  //FRestRequest.AddParameter('nameJson', '{"key":"value"}', TRESTRequestParameterKind.pkREQUESTBODY);
  //FRestRequest.Params.ParameterByName('nameJson').ContentType := TRESTContentType.ctAPPLICATION_JSON;

  //Variante 3
  FRestRequest.Params.AddItem('nameJson', '{"key":"value"}', TRESTRequestParameterKind.pkREQUESTBODY, [], TRESTContentType.ctAPPLICATION_JSON);

  //Variante 4
  //FRestRequest.Body.Add('{"key":"value"}',TRESTContentType.ctAPPLICATION_JSON);

  FRestRequest.AddFile('nameFile', 'PfadZurPng', TRESTContentType.ctIMAGE_PNG);

  FRestRequest.Accept := 'application/json, application/*+json';
  FRestRequest.Execute;
end;
Varianten 1, 2 und 3 führen allen zum gleichen Ergebnis:
Code:
POST /api/derEndpunkt?QueryParameter=1234 HTTP/1.1
Connection: Keep-Alive
Content-Type: multipart/form-data; boundary=--------102722082331395
Accept: application/json, application/*+json
Accept-Charset: UTF-8, *;q=0.8
Authorization: Basic cm9vdDpvcHRpbWFs
Cookie: JSESSIONID=CACA72D331F84414ADF4E7C8CFFE02C2
User-Agent: Embarcadero RESTClient/1.0
Content-Length: 9121
Host: zielhost

----------102722082331395
Content-Disposition: form-data; name="nameJson"
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

{"key":"value"}
----------102722082331395
Content-Disposition: form-data; name="nameFile"; filename="Test_Bild.png"
Content-Type: image/png
Content-Transfer-Encoding: binary

[das serialisierte Bild]
----------102722082331395--
Der Content-Type des Json Parts des Request ist immer text/plain.

Mit Variante 4 wird der Content Type zwar richtig auf application/json gesetzt, der Name ist aber generiert. Klar, habe ja auch keinen explizit angegeben.

Geändert von Rabenrecht (27. Okt 2022 um 07:32 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: MultipartFormData und TRESTRequest

  Alt 27. Okt 2022, 09:45
Debug doch mal mit Debug-DCUs aktiviert rein?
Du müsstest bei beiden Varianten 3 und 4 in einer Überladung von TRESTRequestParameterList.AddItem enden.
Hier kannst du doch feststellen, wer oder was dir den ContentType überschreibt.

Wenn es da noch okay ist, sollte TCustomRESTRequest.Execute das nächste Debug-Ziel sein.
Da gibt es im oberen Drittel irgendwann den Aufruf von TCustomRESTRequest.ContentType().
Hier würde ich debuggen.
Ältere Delphi-Versionen haben da vielleicht noch nicht alle Spezialitäten drin bzw. unterstützen so Multipart-Sachen noch nicht so gut.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#4

AW: MultipartFormData und TRESTRequest

  Alt 27. Okt 2022, 13:44
Das scheint ein Problem mit Delphi 10.2 zu sein. Der verantwortliche Code liegt in in TCustomRESTRequest.DoPrepareRequestBody Zeile 2742
Delphi-Quellcode:
      if LContentType = TRESTContentType.ctMULTIPART_FORM_DATA then
      begin
        // Multipart
        // For multipart names of body parameters are written - in contrast to WWWForm (see below)
        if (LParam.Kind = TRESTRequestParameterKind.pkFile) then
          LMultipartPeerStream.AddFormFile(LParam.Name, LParam.Value, ContentTypeToString(LParam.ContentType))
        else
          LMultipartPeerStream.AddFormField(LParam.Name, LParam.Value);
      end
In Delphi 11 sieht die Sequenz dann so aus
Delphi-Quellcode:
        if SameText(AContentType, TRESTContentType.ctMULTIPART_FORM_DATA) then
        begin
          // Multipart
          // For multipart names of body parameters are written - in contrast to WWWForm (see below)
          if LParam.Stream <> nil then
            LMultipartFormData.AddStream(LParam.Name, LParam.Stream, LParam.Value,
              ContentTypeToString(LParam.ContentType))
          else if LParam.Kind = TRESTRequestParameterKind.pkFile then
            LMultipartFormData.AddFile(LParam.Name, LParam.Value,
              ContentTypeToString(LParam.ContentType))
          else
            LMultipartFormData.AddField(LParam.Name, LParam.Value,
              ContentTypeToString(LParam.ContentType));
        end
Im Gegensatz zu 10.2 wird hier der ContentType des Parameters mit übergeben.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Rabenrecht

Registriert seit: 9. Dez 2016
79 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: MultipartFormData und TRESTRequest

  Alt 27. Okt 2022, 15:10
Ja, habe das jetzt auch so im Code nachvollzogen.

Danke fürs Nachschauen, Uwe!

So, als Workarround hätte ich nun die Option, den Json-Teil des Bodys als Datei zu speichern und dann mit AddFile hinzufügen...

Ich habe geschaut, ob ich das irgendwie austricksen kann, aber sobald LParam.Kind = TRESTRequestParameterKind.pkFile ist, wird der Wert des Parameters als Dateipfad interpretiert.
Mein "Json als Datei abspeichern" Umweg scheint die einzige Möglichkeit zu sein, die mir in Tokyo bleibt

Mal sehen, ob das klappt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz