[Gelöst] PDF im BODY eines HTTP Requests senden

Bild Microsoft Dynamics NAV 2018

[Gelöst] PDF im BODY eines HTTP Requests senden

Beitragvon fips » 19. Juli 2022 09:32

Hallo zusammen,

ich sitze in den letzten Tage an einer Aufgabe, die ich bisher alleine nicht gelöst bekomme, daher mein Ersuchen nach Hilfe :-)

Derzeit entwickle ich eine Schnittstelle aus NAV an ein Telemetriksystem. Dabei erstelle ich XMLs und sende diese an einen Webservice, das funktioniert so weit alles. Die Technik, die ich dazu nutze, habe ich mir hier abgeschaut.

In einem zweiten Schritt möchte ich einen Anhang (Lieferschein als PDF - aus einem NAV Report erstellt) an eine .../file_storage/upload_file.php?... URL senden, die Methode muss dabei 'POST' sein. Auch bis hierhin noch kein Problem, dafür kann ich die webClient.UploadFile(url, 'POST', fileName) nehmen. Zurück kommt laut Schnittstellenbeschreibung eine JSON, die wie folgt aufgebaut ist:
[
{
"name": "file.png",
"status": "OK",
"uuid":"08910afd0bfcc7aa193d40c486ca156a"
}
]

Nun habe ich jedoch keine Ahnung, wie ich die Antwort "einfange" und dann die UUID auslesen kann. Der RĂĽckgabewert von webCient.UploadFile ist ein Byte Array, wo nun meine JSON drin steckt. Nur weiĂź ich nun nicht, wie ich das lesbar mache, so dass ich mir die UUID in NAV wegschreiben kann. Muss dazu sagen, dass ich nur Low Code und C/AL (und ein wenig AL) programmiert habe und kein gelernter Entwickler bin, deswegen oft bei den DotNet-Geschichten an meine Grenzen stoĂźe.

Mein Code sieht (jetzt gerade - nach diversen trial and error) so aus:

System.Net.WebClient.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
System.Net.WebResponse.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'


Code: Alles auswählen
// dotnet webclient Instanz erzeugen
webClient := webClient.WebClient();

// temporäre Datei erzeugen und den namen merken
locFile.CREATETEMPFILE; 
fileName := locFile.NAME;
locFile.CLOSE;

IF locReport.SAVEASPDF(fileName) THEN BEGIN
  // eigentliches uploaden
  WebResponse := webClient.UploadFile(url, 'POST', fileName);
  txt := WebResponse.ToString; 
  MESSAGE(txt);
  // nach dem upload Datei wieder löschen
  ERASE(fileName);
  EXIT(TRUE)
END ELSE
  EXIT(FALSE);


Da kommt dann aber nur ein "Byte[]" raus. Mir ist klar, dass der Code so nicht funktionieren kann, da nach der Zuweisung der Antwort irgendeine Art von Konvertierung fehlt. Aber wie?

Bin fĂĽr jede Hilfestellung danbkar.

MfG
fips
Zuletzt geändert von fips am 4. August 2022 08:28, insgesamt 2-mal geändert.
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon JRenz » 19. Juli 2022 13:00

Hallo,

du könntest mal prüfen, ob eine der Funktionen aus der Codeunit 5459 "JSON Management" dir beim Ermitteln der UUID helfen.
GruĂź
Jörg
JRenz
Microsoft Partner
Microsoft Partner
 
Beiträge: 478
Registriert: 27. April 2007 09:22
Arbeitsort: Neu-Ulm
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2.x bis BC 365

Re: UUID aus JSON auslesen

Beitragvon fips » 19. Juli 2022 13:56

Vielen Dank fĂĽr deine Antwort.

Hilft mir das weiter? Jain.

Wenn ich eine "gefüllte" Instanz JsonArray/JsonObject hätte, dann kann ich mit der CU 5459 den entsprechenden Knoten auslesen. Auf jeden Fall gut zu wissen, dass es eine solche Codeunit gibt.

Mir gelingt aber der Weg vom Ruckgabewert der Funktion [ Dotnet := ] WebClient.UploadFile zur JArray/JObject-Instanz nicht.

Ich bekomme dann die Meldung: "Object serialized to Bytes. JArray instance expected". Da muss ich vermutlich mit einem Convert- oder Deserialize-Befehl (?) arbeiten.

Hat dazu jemand eine Idee?

Hab zuletzt so etwas versucht:
Code: Alles auswählen
WebResponse := webClient.UploadFile(url, 'POST', fileName);
JsonObject := JsonObject.FromObject(WebResponse);
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon Kowa » 19. Juli 2022 14:48

Hier wird Codeunit 1237 Get JSON Structure erweitert, um Werte aus der JSON auszulesen:
https://forum.mibuso.com/discussion/comment/325897
Andere Methode: Ăśber eine eigene .dll, wie hier beschrieben:
https://www.kauffmann.nl/2015/12/03/web-services-examples-part-2-verify-e-mail-address/
GruĂź, Kai

Frage beantwortet? Schreibe bitte [Gelöst] vor den Titel des ersten Beitrags.
Bitte erst suchen, dann fragen. Bitte beachte den kleinen Community-Knigge.
Kein Support per PN, Mail, Messenger oder Telefon! DafĂĽr ist dieses Forum da.

Download: Dynamics NAV Object Text Explorer (Alternativlink). MVP Alumni
Benutzeravatar
Kowa
Moderator
Moderator
 
Beiträge: 7827
Registriert: 17. Juni 2005 17:32
Wohnort: Bremen
Realer Name: Kai Kowalewski
Arbeitsort: Osterholz-Scharmbeck
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics 365
Microsoft Dynamics Version: BC, NAV 2018 bis Navision 2.01

Re: UUID aus JSON auslesen

Beitragvon fips » 19. Juli 2022 15:03

Vielen Dank, Kowa. Die Links sind mir bekannt :-).

Leider ist das Auslesen selbst nicht mein Problem. Selbst wenn ich Text als Parameter hätte, käme ich schon weiter. Oder ich verstehe etwas grundsätzliches nicht.

Ich verstehe nicht, wie ich den Rückgabewert (DotNet) von Webclient.UploadFile "greifen" kann und in eine JObject/JArray/JsonReader o.ä. überführen kann.

Also im Grunde suche ich eine Methode um aus dem ByteArray, was zurĂĽckommt eine Txt/Json/XML - Instanz oder irgendwas lesebares zu machen, mit der ich dann umgehen kann.
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon Ermac » 20. Juli 2022 10:37

Hallo,
warum so kompliziert? Dynamics NAV bringt doch alles mit. Den DotNet-Datentyp WebClient solltest du ĂĽbrigens nicht mehr verwenden, da obsolet.
Du könntest mit der Codeunit 1297 Http Web Request Mgt. und der Tabelle 1236 JSON Buffer arbeiten. Die nehmen dir vieles ab. Der JSON Buffer ist sowas wie der Excel-Buffer, nur halt für JSON.

Hier ist ein wenig ungetesteter Beispielcode. Das Lesen deiner PDF-Datei musst du sicherlich anpassen. Ggf. mit dem File Management arbeiten. Aber prinzipiell ist das die Vorgehensweise. Wenn du nicht mit dem JSON Buffer arbeiten möchtest, hast du so immerhin dein zurückgegebenes JSON in Textform - die eigentliche Lösung für deine Frage :)
Name DataType Subtype Length
TempBlob Record TempBlob temporary
TempJSONBuffer Record JSON Buffer temporary
HttpWebRequestMgt Codeunit Http Web Request Mgt.
ResponseJsonText Text
Txt Text 100
NumRead Integer
f File
ins InStream
outs OutStream
HttpStatusCode DotNet System.Net.HttpStatusCode.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
ResponseHeaders DotNet System.Collections.Specialized.NameValueCollection.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Code: Alles auswählen
IF NOT f.OPEN('C:\Temp\Test.pdf') THEN
  EXIT;
 
CLEAR(HttpWebRequestMgt);
HttpWebRequestMgt.Initialize('http://myurl.com');
HttpWebRequestMgt.SetMethod('POST');
HttpWebRequestMgt.SetContentType('application/octet-stream');
HttpWebRequestMgt.SetContentLength(f.LEN());
HttpWebRequestMgt.SetUserAgent('Dynamics NAV 2018 Client');
 
f.CREATEINSTREAM(ins);
CLEAR(TempBlob);
TempBlob.Blob.CREATEOUTSTREAM(outs);
COPYSTREAM(outs, ins);
HttpWebRequestMgt.AddBodyBlob(TempBlob);
 
f.CLOSE();

CLEAR(ins);
 
IF NOT HttpWebRequestMgt.GetResponse(ins, HttpStatusCode, ResponseHeaders) THEN
  EXIT;

// TODO: StautsCode ggf. abfragen

CLEAR(ResponseJsonText);
WHILE NOT ins.EOS() DO BEGIN
  NumRead := ins.READTEXT(Txt, 100);
  IF NumRead > 0 THEN
    ResponseJsonText := ResponseJsonText + Txt;
END;

TempJSONBuffer.RESET();
TempJSONBuffer.DELETEALL();
TempJSONBuffer.ReadFromText(ResponseJsonText);
IF TempJSONBuffer.FINDSET() THEN
  REPEAT
    // TODO ...
  UNTIL TempJSONBuffer.NEXT() = 0;
Ermac
 
Beiträge: 32
Registriert: 29. Juni 2016 11:42
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV

Re: UUID aus JSON auslesen

Beitragvon fips » 21. Juli 2022 10:11

Hallo Ermac,

vielen, vielen Dank. Das kann mir die Woche noch irgendwie retten ... ;-).

Hab deinen Code (also den Upload-teil) erstmal übernommen, die URL ersetzt und den Filename auf meine PDF gematcht, die ich hochladen möchte. locFile2.OPEN funktioniert auch noch. Leider kommt HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeaders) immer mit FALSE zurück und ich sehe noch nicht warum.

Hier mein Code (wird später noch aufgeräumt):

Code: Alles auswählen
IF locReport.SAVEASPDF(fileName) THEN BEGIN
    // eigentliches uploaden
    IF NOT locFile2.OPEN(fileName) THEN
      ERROR('File could not be open');

    CLEAR(HttpWebRequestMgt);
    HttpWebRequestMgt.Initialize(url);
    HttpWebRequestMgt.SetMethod('POST');
    HttpWebRequestMgt.SetContentType('application/octet-stream');
    HttpWebRequestMgt.SetContentLength(locFile2.LEN);
    HttpWebRequestMgt.SetUserAgent('Dynamics NAV 2018 Client');

    HttpWebRequestMgt.SetReturnType('application/json'); //!
    HttpWebRequestMgt.AddSecurityProtocolTls12; //!

    locFile2.CREATEINSTREAM(InStr);
    CLEAR(TempBlob);
    TempBlob.Blob.CREATEOUTSTREAM(OutStr);
    COPYSTREAM(OutStr, InStr);
    HttpWebRequestMgt.AddBodyBlob(TempBlob);
 
    locFile2.CLOSE();

    CLEAR(InStr);
   
    IF NOT HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeaders) THEN
      ERROR('Cannot get response.');

    //CheckStatusCode
    //...


Woran kann das liegen?

mfG fips


EDIT* Hab nun noch den ReturnType auf "application/json" gesetzt, leider weiterhin ohne Erfolg.
EDIT** HttpWebRequestMgt.AddSecurityProtocolTls12 ergänzt, kein anderes Ergebnis
EDIT*** Eben erfahren, dass schon der Upload nicht funktioniert hat. Das Verzeichnis, in das die PDFs hochgeladen werden, ist leer. Aber das liegt vermutlich an dem Rollback nach Fehler, ist ja alles eine Transaktion.
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon fips » 22. Juli 2022 11:47

Hallo nochmal,

in der Hoffnung, dass vielleicht noch jemand eine Idee hat.
Ich weiß mittlerweile, an welcher Stelle im Code NAV auf den Fehler läuft:

Codeunit 1299 Web Request Helper:

Code: Alles auswählen
[TryFunction] GetWebResponse(VAR HttpWebRequest : DotNet "System.Net.HttpWebRequest";VAR HttpWebResponse : DotNet "System.Net.HttpWebResponse";VAR ResponseInStream : InStream;VAR HttpStatusCode : DotNet "System.Net.HttpStatusCode";VAR ResponseHeaders

IF ProgressDialogEnabled THEN
  ProcessingWindow.OPEN(ProcessingWindowMsg);

CLEARLASTERROR;
HttpWebResponse := HttpWebRequest.GetResponse;
HttpWebResponse.GetResponseStream.CopyTo(ResponseInStream); //fails <---!!!---
HttpStatusCode := HttpWebResponse.StatusCode;
ResponseHeaders := HttpWebResponse.Headers;

IF ProgressDialogEnabled THEN
  ProcessingWindow.CLOSE;


Leider kann ich da dann nicht mehr weiter reinschauen/debuggen.

mfG fips
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon sweikelt » 22. Juli 2022 13:41

aber du bekommst doch sicherlich eine Fehlermeldung, oder?
Benutzeravatar
sweikelt
Microsoft Partner
Microsoft Partner
 
Beiträge: 1774
Registriert: 18. November 2010 10:15
Wohnort: Oschatz
Realer Name: Stephan Weikelt
Arbeitsort: Berlin
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 3-2018 | D365BC

Re: UUID aus JSON auslesen

Beitragvon fips » 22. Juli 2022 13:45

Hab nun ein ERROR(GETLASTERRORTEXT) eingebaut, das gibt mir nun "Variable Microsoft.Dynamics.Nav.Runtime.NavInstream nicht initialisiert."
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon fiddi » 22. Juli 2022 14:08

Hallo,

hast du denn ResponseInStream vor dem Aufruf der Funktion initialisert?

GruĂź Fiddi
Wer aufhört besser zu werden, hat aufgehört gut zu sein. (frei nach Philip Rosenthal)
Frage beantwortet? Schreibe bitte [Gelöst] vor den Titel des ersten Beitrags.
Bitte erst suchen, dann fragen. Bitte beachte den kleinen Community-Knigge.
Kein Support per PN, Mail, IM oder Telefon! DafĂĽr ist dieses Forum da.
fiddi
Moderator
Moderator
 
Beiträge: 7088
Registriert: 9. Juni 2008 10:13
Realer Name: Hans Heinrich Fiddelke
Arbeitsort: Bremen
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: NAV2.6-aktuell

Re: UUID aus JSON auslesen

Beitragvon fips » 22. Juli 2022 15:14

Hallo nochmal,

habe ich nun gemacht (glaube ich). Jetzt bekomme ich auch aus der Antwort "ERROR:MISSING_FILE". Das ist auch schon eine Antwort vom Server, den ich anspreche.

Mein Code sieht nun wie folgt aus:
Code: Alles auswählen
  IF locReport.SAVEASPDF(fileName) THEN BEGIN
    // eigentliches uploaden
    IF NOT locFile2.OPEN(fileName) THEN
      ERROR('File could not be opened');

    CLEAR(HttpWebRequestMgt);
    HttpWebRequestMgt.Initialize(url);
    HttpWebRequestMgt.SetMethod('POST');
    //HttpWebRequestMgt.SetContentType('multipart/form-data');
    HttpWebRequestMgt.SetContentType('application/octet-stream');
    HttpWebRequestMgt.SetContentLength(locFile2.LEN);
    HttpWebRequestMgt.SetUserAgent('Dynamics NAV 2018 Client');
    HttpWebRequestMgt.SetReturnType('application/json'); //!!!
    HttpWebRequestMgt.AddSecurityProtocolTls12; //!!!
    HttpWebRequestMgt.DisableUI; //!!!
   

    locFile2.CREATEINSTREAM(InStr);
    CLEAR(TempBlob);   
    TempBlob.Blob.CREATEOUTSTREAM(OutStr);
    COPYSTREAM(OutStr, InStr);
    HttpWebRequestMgt.AddBodyBlob(TempBlob);
   
    locFile2.CLOSE();
   
    CLEAR(InStr);
   
    HttpWebRequestMgt.CreateInstream(InStr);  //<--Initialisieren-->?
    IF NOT HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeaders) THEN
      ERROR(GETLASTERRORTEXT);

    //CheckStatusCode
    //...

    //process JSON
    CLEAR(ResponseJsonText);
    WHILE NOT InStr.EOS() DO BEGIN
      NumRead := InStr.READTEXT(txt, 100);
      IF NumRead > 0 THEN
        ResponseJsonText := ResponseJsonText + txt;
    END;

    MESSAGE(ResponseJsonText);
   
    // nach dem upload Datei wieder löschen
    ERASE(fileName);
    EXIT(TRUE)
  END ELSE
    EXIT(FALSE);


Nun geht es also noch darum, warum er die PDF nicht erkennt.

Ich hatte die Fehlermeldung schon einmal, als ich den Request ĂĽber die Postman App versucht habe zu senden. Da war der Grund, dass ich die Datei versucht habe als binary mitzusenden statt als FormData. Damit hat es dann aber funktioniert.

Kann das der Grund sein? Ist die Initialisierung (im Code gekennzeichnet) richtig?
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon sweikelt » 22. Juli 2022 15:15

genau das konnte ich mir denken :)
schau mal hier
https://forum.mibuso.com/discussion/68873/outstream-initialize-error
Benutzeravatar
sweikelt
Microsoft Partner
Microsoft Partner
 
Beiträge: 1774
Registriert: 18. November 2010 10:15
Wohnort: Oschatz
Realer Name: Stephan Weikelt
Arbeitsort: Berlin
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 3-2018 | D365BC

Re: UUID aus JSON auslesen

Beitragvon fips » 22. Juli 2022 15:31

Hallo sweikelt,

war das die Antwort auf meinen letzten Beitrag?

Es werden doch nun beide initialisiert, oder sehe ich das falsch? Vielleicht hab ich auch nun zu lange auf den gleichen Code geschaut, das mag ich nicht ausschlieĂźen.. :-?
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon sweikelt » 22. Juli 2022 19:42

Hi,
das war leider zu spät von mir gesendet - sollte auf das Init des Stream kommen (direkt nach Kowa).

Welche Fehlermeldung und vor allem an welcher Codestelle kommt?
Benutzeravatar
sweikelt
Microsoft Partner
Microsoft Partner
 
Beiträge: 1774
Registriert: 18. November 2010 10:15
Wohnort: Oschatz
Realer Name: Stephan Weikelt
Arbeitsort: Berlin
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 3-2018 | D365BC

Re: UUID aus JSON auslesen

Beitragvon fips » 25. Juli 2022 07:43

fips hat geschrieben:Hallo nochmal,

habe ich nun gemacht (glaube ich). Jetzt bekomme ich auch aus der Antwort "ERROR:MISSING_FILE". Das ist auch schon eine Antwort vom Server, den ich anspreche.

Mein Code sieht nun wie folgt aus:
Code: Alles auswählen
  IF locReport.SAVEASPDF(fileName) THEN BEGIN
    // eigentliches uploaden
    IF NOT locFile2.OPEN(fileName) THEN
      ERROR('File could not be opened');

    CLEAR(HttpWebRequestMgt);
    HttpWebRequestMgt.Initialize(url);
    HttpWebRequestMgt.SetMethod('POST');
    //HttpWebRequestMgt.SetContentType('multipart/form-data');
    HttpWebRequestMgt.SetContentType('application/octet-stream');
    HttpWebRequestMgt.SetContentLength(locFile2.LEN);
    HttpWebRequestMgt.SetUserAgent('Dynamics NAV 2018 Client');
    HttpWebRequestMgt.SetReturnType('application/json'); //!!!
    HttpWebRequestMgt.AddSecurityProtocolTls12; //!!!
    HttpWebRequestMgt.DisableUI; //!!!
   

    locFile2.CREATEINSTREAM(InStr);
    CLEAR(TempBlob);   
    TempBlob.Blob.CREATEOUTSTREAM(OutStr);
    COPYSTREAM(OutStr, InStr);
    HttpWebRequestMgt.AddBodyBlob(TempBlob);
   
    locFile2.CLOSE();
   
    CLEAR(InStr);
   
    HttpWebRequestMgt.CreateInstream(InStr);  //<--Initialisieren-->?
    IF NOT HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeaders) THEN
      ERROR(GETLASTERRORTEXT);

    //CheckStatusCode
    //...

    //process JSON
    CLEAR(ResponseJsonText);
    WHILE NOT InStr.EOS() DO BEGIN
      NumRead := InStr.READTEXT(txt, 100);
      IF NumRead > 0 THEN
        ResponseJsonText := ResponseJsonText + txt;
    END;

    MESSAGE(ResponseJsonText);
   
    // nach dem upload Datei wieder löschen
    ERASE(fileName);
    EXIT(TRUE)
  END ELSE
    EXIT(FALSE);


Nun geht es also noch darum, warum er die PDF nicht erkennt.

Ich hatte die Fehlermeldung schon einmal, als ich den Request ĂĽber die Postman App versucht habe zu senden. Da war der Grund, dass ich die Datei versucht habe als binary mitzusenden statt als FormData. Damit hat es dann aber funktioniert.

Kann das der Grund sein? Ist die Initialisierung (im Code gekennzeichnet) richtig?



Hi zusammen,

also wie schon am Freitag geschrieben gibt es keinen "harten" Error mehr sondern er geht tatsächlich an der MESSAGE(ResponseJsonText) raus mit der Antwort der Gegenstelle, aber halt "ERROR:MISSING_FILE" (siehe zitierter Beitrag).

Es scheint also etwas mit dem Anhängen der PDF an den Request noch nicht zu funktionieren. Ermac meinte ja auch, dass ich das einlesen vermutlich nochmal anschauen muss. Bin weiterhin für jeden Hinweis dankbar.

Danke und guten Start in die Woche :-)
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon fips » 26. Juli 2022 11:25

Hat noch irgendwer eine Idee? Ich habe das GefĂĽhl, dass nicht mehr viel fehlt. Ich bekomme ja bereits eine Antwort zu der Request, aber halt ERROR:MISSING_FILE.
Das hinzugefügte BLOB wird aus irgendeinem Grund nich erkannt, obwohl es nichtleer ist. An der PDF selbst liegt es nicht, ich konnte dieselbige via Postman App erfolgreich hochladen. Ich vermute, dass ich das über den ContentType steuern muss, aber habe schon alles ausprobiert, was mir einfällt.

Hier mein aktueller Stand an Code:

Code: Alles auswählen
IF locReport.SAVEASPDF(fileName) THEN BEGIN
    // eigentliches uploaden
    IF NOT locFile2.OPEN(fileName) THEN
      ERROR('File could not be opened');

    CLEAR(HttpWebRequestMgt);
    HttpWebRequestMgt.Initialize(url);
    HttpWebRequestMgt.SetMethod('POST');
    //HttpWebRequestMgt.SetContentType('multipart/form-data');
    //HttpWebRequestMgt.SetContentType('application/octet-stream');
    HttpWebRequestMgt.SetContentType('application/x-www-form-urlencoded');
    //HttpWebRequestMgt.SetContentType('application/form-data');
    HttpWebRequestMgt.SetContentLength(locFile2.LEN);
    HttpWebRequestMgt.SetUserAgent('Dynamics NAV 2018 Client');
    HttpWebRequestMgt.SetReturnType('application/json');
    HttpWebRequestMgt.AddSecurityProtocolTls12;
    HttpWebRequestMgt.DisableUI;

    FileManagement.BLOBImportFromServerFile(TempBlob,fileName);
    HttpWebRequestMgt.AddBodyBlob(TempBlob);
   
    locFile2.CLOSE();   
   
    CLEAR(TempBlob);
   
    HttpWebRequestMgt.CreateInstream(InStr);  //<--Initialisieren-->?
   
    IF NOT HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeaders) THEN
      ERROR(GETLASTERRORTEXT);

    //CheckStatusCode
    //...

    //process JSON
    CLEAR(ResponseJsonText);
    WHILE NOT InStr.EOS() DO BEGIN
      NumRead := InStr.READTEXT(txt, 100);
      IF NumRead > 0 THEN
        ResponseJsonText := ResponseJsonText + txt;
    END;

    MESSAGE(ResponseJsonText); //<---Hier kommt "ERROR:MISSING_FILE
   
    // nach dem upload Datei wieder löschen
    ERASE(fileName);
    EXIT(TRUE)
  END ELSE
    EXIT(FALSE)
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: UUID aus JSON auslesen

Beitragvon sweikelt » 27. Juli 2022 09:13

also ich kein Profi, aber mĂĽsstest du nicht
Code: Alles auswählen
HttpWebRequestMgt.SendRequestAndReadResponse()

ausfĂĽhren?
Du machst nur GetResponse, aber da wird doch nix gesendet

Edit - sorry, ich hoffe das gibt es schon in NAV2018 -> hab grad nur in BC18 geschaut
Benutzeravatar
sweikelt
Microsoft Partner
Microsoft Partner
 
Beiträge: 1774
Registriert: 18. November 2010 10:15
Wohnort: Oschatz
Realer Name: Stephan Weikelt
Arbeitsort: Berlin
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 3-2018 | D365BC

Re: UUID aus JSON auslesen

Beitragvon fips » 27. Juli 2022 10:14

Das habe ich mir auch die ganze Zeit gedacht (halt auch kein Profi :wink: ). Bei Postman z.Bb klicke ich ja auch irgendwann auf "Senden". Aber das machen andere - funktionierende - Code Beispiele auch nicht, weder in C# noch in C/AL. Es wird immer nur das BLOB eingefĂĽgt und dann die Anwort gefordert.

In NAV18 steht die Funktion auch nicht zur Verfügung. Hast du die Möglichkeit, da reinzuschauen? Macht die denn etwas anderes als mein Code an der Stelle?
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: PDF im BODY eines HTTP Requests senden

Beitragvon fips » 2. August 2022 10:09

Hallo nochmal,

was die Funktion in BC macht, konnte ich nun selbst rausfinden. Leider grundlegend nichts anderes, als was ich hier mache.

Konnte mittlerweile feststellen, dass es ohne Angabe der Boundaries nicht funktioniert. Über Postman App geht es z.b. ohne Angabe von Boundaries auch nicht. Also habe ich diese ergänzt. Weiterhin leider ohne Erfolg, es kommt unten in der Message immer noch "ERROR:Missing_File" als Antwort von der Schnittstelle zurück.

AuĂźerdem habe ich noch den Header aufgehĂĽbscht:
HttpWebRequestMgt.AddHeader('Accept-Encoding','gzip, deflate, br');
HttpWebRequestMgt.AddHeader('Content-Encoding','gzip, deflate, br');

Etwas Kosmetik, leider gleiches Ergebnis.

Auf StackOverflow gab es noch die Idee, das ganze base64 zu converten, habe ich ebenfalls ausprobiert. Auch hier unverändertes Ergebnis (hatte ich auch erwartet, Postman macht das z.b. auch nicht und sendet mit Erfolg, war eher aus der Verzweiflung heraus).

Bin leider mit meinem Latein am Ende. Bleibt mir noch beim Telemetrik-Anbieter zu Fragen, ob es andere NAV-Kunden gab, die das erfolgreich umgesetzt haben oder hier auf eine Antwort zu hoffen. Vielleicht sieht ja jemand noch den Denkfehler.

Mein aktueller Code:
Code: Alles auswählen
IF SalesShipmentHeader.FINDFIRST THEN BEGIN
  locReport.SETTABLEVIEW(SalesShipmentHeader);
  IF locReport.SAVEASPDF(fileName) THEN BEGIN
    // eigentliches uploaden
    IF NOT locFile2.OPEN(fileName) THEN
      ERROR('File could not be opened');

    CLEAR(HttpWebRequestMgt);
    HttpWebRequestMgt.Initialize(url);
    HttpWebRequestMgt.DisableUI;
    HttpWebRequestMgt.SetMethod('POST');
    HttpWebRequestMgt.SetContentType('multipart/form-data; boundary=--123456789');
    //HttpWebRequestMgt.SetContentType('multipart/form-data');
    //HttpWebRequestMgt.SetContentType('application/octet-stream);
    //HttpWebRequestMgt.SetContentType('application/x-www-form-urlencoded');
    //HttpWebRequestMgt.SetContentType('application/form-data');
    //HttpWebRequestMgt.SetContentType('application/binary')
    //HttpWebRequestMgt.SetContentType('application/pdf);
    HttpWebRequestMgt.SetContentLength(locFile2.LEN);   
    HttpWebRequestMgt.SetUserAgent('Dynamics NAV 2018 Client');
    HttpWebRequestMgt.SetReturnType('application/json');
    HttpWebRequestMgt.AddSecurityProtocolTls12;
    HttpWebRequestMgt.AddHeader('Accept-Encoding','gzip, deflate, br');
    HttpWebRequestMgt.AddHeader('Content-Encoding','gzip, deflate, br');

    FileManagement.BLOBImportFromServerFile(TempBlob,fileName);
    HttpWebRequestMgt.AddBodyBlob(TempBlob);     
   
    locFile2.CLOSE();   
   
    CLEAR(TempBlob);
   
    HttpWebRequestMgt.CreateInstream(InStr); 
   
    IF NOT HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeaders) THEN
      ERROR(GETLASTERRORTEXT);

    //CheckStatusCode
    //...

    //process JSON
    CLEAR(ResponseJsonText);
    WHILE NOT InStr.EOS() DO BEGIN
      NumRead := InStr.READTEXT(txt, 100);
      IF NumRead > 0 THEN
        ResponseJsonText := ResponseJsonText + txt;
    END;

    MESSAGE(ResponseJsonText);
   
    // nach dem upload Datei wieder löschen
    ERASE(fileName);
    EXIT(TRUE)
  END ELSE
    EXIT(FALSE);
END;

EXIT(FALSE)



P.S: Dieser Blog scheint es übrigens gelöst zu haben, leider sind die Screenshots nicht mehr online. Anhand der Kommentare bekomme ich es aber nicht nachvollzogen.
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: PDF im BODY eines HTTP Requests senden

Beitragvon Furean » 2. August 2022 12:37

Hallo,
ich hab mir das mal kurz angeschaut. Hast du Zugriff auf den PHP Code, bzw. kannst du diesen teilen?
Die Ăśbergabe funktioniert, allerdings musst du darauf in PHP ĂĽber $_POST zugreifen und ggf. noch umwandeln, ich denke mal dass hier das Problem liegt.
Furean
 
Beiträge: 29
Registriert: 15. Oktober 2020 14:02

Re: PDF im BODY eines HTTP Requests senden

Beitragvon fips » 2. August 2022 13:03

Hallo und danke!

Das ist ja schonmal gut zu wissen. Die PHP-Datei ist leider vom Drittanbieter, daher hab ich - Stand jetzt - keinen Zugriff bzw. keine Handhabe.

Werde das aber mal anfragen.
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: PDF im BODY eines HTTP Requests senden

Beitragvon Furean » 2. August 2022 13:42

Ah okay,
hat bei dir der Code im ersten Beitrag funktioniert? Also wurde dort die Datei abgelegt und nur der RĂĽckgabewert war das Problem?
Dort wird am Ende mit PHP per $_FILES darauf zugegriffen, was einen Unterschied macht.
Furean
 
Beiträge: 29
Registriert: 15. Oktober 2020 14:02

Re: PDF im BODY eines HTTP Requests senden

Beitragvon fips » 2. August 2022 14:11

Du meinst den hier?

Code: Alles auswählen
// dotnet webclient Instanz erzeugen
webClient := webClient.WebClient();

// temporäre Datei erzeugen und den namen merken
locFile.CREATETEMPFILE;
fileName := locFile.NAME;
locFile.CLOSE;

IF locReport.SAVEASPDF(fileName) THEN BEGIN
  // eigentliches uploaden
  WebResponse := webClient.UploadFile(url, 'POST', fileName);
  txt := WebResponse.ToString;
  MESSAGE(txt);
  // nach dem upload Datei wieder löschen
  ERASE(fileName);
  EXIT(TRUE)
END ELSE
  EXIT(FALSE);


Hier weiĂź ich nicht ob der Upload funktioniert hatte, konnte die RĂĽckgabe ja nicht einfangen.
fips
 
Beiträge: 29
Registriert: 16. Juli 2020 10:13
Bezug zu Microsoft Dynamics: End-Anwender
Microsoft Dynamics Produkt: Microsoft Dynamics NAV
Microsoft Dynamics Version: 2018

Re: PDF im BODY eines HTTP Requests senden

Beitragvon Furean » 2. August 2022 14:37

Ja genau,
fĂĽr den RĂĽckgabewert mĂĽsstest du ein DotNet Array erstellen und dann ausgeben.
Bei dir wĂĽrde das heiĂźen, das WebResponse mĂĽsste folgendes sein:
System.Array.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

AnschlieĂźend erstellst du noch eine neue Variable:
System.Text.Encoding.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

Damit kannst du dann die Antwort in einen String umwandeln und dir direkt ausgeben lassen. Das kann dann folgendermaĂźen aussehen:
Code: Alles auswählen
 WebResponse := webClient.UploadFile(url, 'POST', fileName);
 txtstring := txtstring.Default;
 Txt := txtstring.GetString(WebResponse);
 MESSAGE(Txt);


txtstring wäre hier die neue Variable.
Furean
 
Beiträge: 29
Registriert: 15. Oktober 2020 14:02

Nächste

ZurĂĽck zu NAV 2018

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast