![]() |
Delphi-Version: 10 Seattle
ContentType in TRESTClient
Hallo zusammen,
wir sind in unserer Firma gerade dabei, von Seattle auf 10.3.1 Rio umzusteigen, was einige Probleme verursacht hat. Die meisten davon konnte man leicht lösen, beim TRESTClient bin ich aber auf eine sehr merkwürdige Implementierung gestoßen, die - soweit ich das bislang einschätzen kann - den TRESTClient unbrauchbar macht. Meine Hoffnung ist, dass das Problem darin besteht, dass ich den Rest-Client bisher falsch benutzt habe. Deshalb richte ich die Frage mal hier ins Forum und hoffe, dass mir jemand helfen kann: Wie setzt man den content-type für einen Request richtig? Ich benutze den TRESTClient beispielsweise für eine Kommunikation mit Klarna und Klarna erwartet als content-type so etwas wie "application/vnd.klarna.checkout.aggregated-order-v2+json". Das Problem ist, dass der TRESTClient den content-type in der Execute-Methode jedes Mal durch einen der X verschiedenen "Standard"-content-types ersetzt, in meinem Fall beispielsweise durch "application/json". Das führt dazu, dass Klarna sich mit der Meldung "415 Unsupported Media Type" zurückmeldet und ich keine erfolgreiche Anfrage mehr durch bekomme. Bei der "alten" Delphi-Version wurde, nachdem der content-type in der Execute-Methode überschrieben wurde, die virtuelle Methode "DoPrepareRequestBody" aufgerufen, die wir dazu misbraucht haben, den content-type wieder auf den gewünschten Wert zu setzen. Bei Rio hat sich hier aber die Reihenfolge vertauscht, so dass dies jetzt nicht mehr möglich ist. |
AW: ContentType in TRESTClient
Nur eine Idee:
Wäre es für euch eine Möglichkeit, die Unit REST.Types zu kopieren, mit in euer Projekt aufzunehmen und zu patchen? So dass ihr euren Typ in TRESTContentType und entsprechend
Delphi-Quellcode:
anpasst?
function ContentTypeToString(AContentType: TRESTContentType): string;
Man müsste aber prüfen, in wie weit das mit den anderen REST-Units dann noch kompatibel ist. Ggf. muss man sich mehrere davon ins Projekt nehmen. Dann kann man aber auch gleich die Execute-Methode anpassen. Weitere Möglichkeit: Unter Windows würde die Möglichkeit bestehen, sich in die Winapi-Funktion WinHttpAddRequestHeaders reinzuhängen (intercept) und den Wert beim Aufruf dort auszutauschen. Diese wird in procedure
Delphi-Quellcode:
aus System.Net.HttpClient.Win aufgerufen.
TWinHTTPRequest.AddHeader(const AName, AValue: string);
Natürlich insofern, dass dies in Rio verwendet wird. Ich kann im Moment nur in Tokyo nachschauen. |
AW: ContentType in TRESTClient
|
AW: ContentType in TRESTClient
|
AW: ContentType in TRESTClient
Zitat:
Ich bin mir nur nicht sicher, ob das mit dem content-type ein Bug ist oder ein Feature ;) Letzteres würde bedeuten, dass man beim zukünftigen Wechsel auf neuere Delphi-Versionen immer wieder die Implementierung anpassen muss. Zitat:
Aber danke jedenfalls schon mal für die Idee und den Link! |
AW: ContentType in TRESTClient
Zitat:
Klar, es ist etwas tricky, falls die Contenttypes variieren, aber man kann sich da ggf. mit etwas Globalen behelfen(oh mein Gott, hat er das wirklich geschrieben?). Also an einer Stelle (eigene Unit) den aktuellen, jetzt gleich zu verwendeten Contenttype setzen (also bevor ihr Request.Execute aufruft) und im Intercepter auslesen und ersetzen. Klar ist das alles nur Gebastel, aber euren Code jetzt komplett auf eine saubere Lösung wie von Schokohase vorgeschlagen umzustricken, könnt ihr machen wenn ganz viel Zeit ist. Mit der Intercept-Lösung könnt ihr ja per {IFDEF Compilerversion=XYZ} arbeiten. So dass ihr in der ggf. nächsten Version den Fix nicht verwenden müsst, wenn da alles wieder schön sein sollte. |
AW: ContentType in TRESTClient
Eine einfache Lösung habe ich leider auch nicht, aber ich hatte vor einiger Zeit das selbe Problem und hatte dafür mal ein Ticket aufgemacht mit einem einfachen Lösungsvorschlag.
![]() Vielleicht könnt ihr ja mal dafür voten oder kommentieren, in der Hoffnung, dass es dann auch mal umgesetzt wird. |
AW: ContentType in TRESTClient
So geht es also definitiv nicht?
Delphi-Quellcode:
RestClient.ContentType := 'application/veryspecialjson+V42';
RestRequest.Params.AddItem('Content-Type', RestClient.ContentType, TRESTRequestParameterKind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode], TRESTContentType.ctNone); |
AW: ContentType in TRESTClient
Wenn ich mich an meine Odysee von vor einem Jahr richtig erinnere, hast du dann den Content-Type entweder doppelt drin stehen - also einmal den selbst gesetzten und den automatischen - oder es wird das eigene Feld doch wieder überschrieben. Ich meine, es war ersteres, also dass er doppelt vorkommt.
|
AW: ContentType in TRESTClient
Zitat:
Zitat:
Irgendwas habe ich gestern wohl falsch gemacht. Ich halte es zwar für ein falsches Design, dass die Property "ContentType" von außen gesetzt werden kann, obwohl das überhaupt keine Auswirkung auf den Request hat, aber nun ja, für mich zählt erst einmal, dass ich eine (einfache) Lösung habe. Danke jedenfalls für eure Hilfe :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 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 by Thomas Breitkreuz