IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Création d'un body JSON avec TRESTRequest, delphi 10.3


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 36
    Par défaut Création d'un body JSON avec TRESTRequest, delphi 10.3
    Bonjour à tous
    je dois faire une application en Delphi 10.3 pour faire signer des documents PDF avec Yousign (un site de signature électronique)
    J'arrive à faire un GET : l'authentification se passe correctement et je récupère les noms de signataires en format JSON

    Il faut maintenant que j'envoie un PDF à signer encodé en 64bits
    le body doit comporter 2 valeurs : le nom (name) et le fichier PDF encodé (content)

    avec Postman, tout se passe bien
    {
    "name": "MonFichier.pdf",
    "content": "JVBERi0xLjMNJeLjz9MNCjIzMCAwIG9iag08PC9MaW5lYXJpemVkIDEvTCAxMTI1 etc .."



    J’utilise les composants TRESTClient, TRESTRequest et TRESTResponse
    Le serveur me renvoie l'erreur 400 Bad Request
    Je pense que c'est la création de mon JSON à envoyer qui n'est pas correct

    voici mon source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    procedure TFYS_principale.BPostFilesClick(Sender: TObject);
    var
      inStream: TStream;
      outStream: TStream;
    begin
     
      // chargement du fichier PDF dans un stream
      inStream := TFileStream.Create('c:\testpdf\test.pdf', fmOpenRead);
     
      outStream := TStringStream.Create;
     
      // encodage en 64 bits
      TNetEncoding.Base64.Encode(inStream, outStream);
     
     
      outStream.Position := 0;
     
      LJSONObject.AddPair('name','MonFichier.pdf');
      LJSONObject.AddPair('content', outStream.ToString);
     
      MonRESTRequest.AddBody(LJSONObject);
     
      MonRESTRequest.Execute;
      Restrequest_PostFiles.Execute;    // ERREUR 400 : bad request !
     
      memo.Text := RESTResponse_PostFiles.JSONText;
     
     
    end;
    Si quelqu'un peut m'aider, ça m'avancerait beaucoup

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 001
    Par défaut
    outStream.DataString plutot que ToString ?
    Confusion entre Restrequest_PostFiles et MonRESTRequest ?
    Evitez les objets globaux, je te recommande pour le vrai code d'isoler cela dans un objet TMonClientBidule, pour que le source de la forme ne contiennent pas ce type de code plutôt Modèle que View.

    Code tapé sur le forum, alors il y aura surement quelques erreurs, cela vous donne un aperçu d'un code complet et indépendant de la form (suffira juste de faire une fonction à la place pour alimenter memo.Text)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    procedure TFYS_principale.BPostFilesClick(Sender: TObject);
    var
      inStream: TStream;
      outStream: TStream;
      RESTClient: TRESTClient;
      RESTClient: TRESTRequest;
      LJSONObject: TJSONObject;
    begin
     
      // chargement du fichier PDF dans un stream
      inStream := TFileStream.Create('c:\testpdf\test.pdf', fmOpenRead);
      try
        outStream := TStringStream.Create;
        try
          // encodage en 64 bits
          TNetEncoding.Base64.Encode(inStream, outStream);
     
         RESTClient := TRESTClient.Create(URL); // URL contient juste https://server/service/
         try
           RESTClient.ContentType := 'application/json; charset=utf-8'; // voir ce qui est nécessaire
     
            RESTRequest := TRESTRequest.Create(nil);
            try
              RESTRequest.Resource := fonction; // optionnel c'est la fonction REST, on a une une adresse https://server/service/fonction
              RESTRequest.Method := TRESTRequestMethod.rmPOST;
     
              RESTRequest.Client := RESTClient;
     
              LJSONObject := TJSONObject.Create();
              try
                LJSONObject.AddPair('name','MonFichier.pdf'); // prévoir un TEncoding.UTF8.Encode
                LJSONObject.AddPair('content', outStream.DataString);
                RESTRequest.AddBody(LJSONObject);
              finally
                LJSONObject.Free();
              end;
     
              RESTRequest.Execute();
              memo.Text := RESTRequest.Response.Content; // ou Request.Response.JSONText
            finally
              RESTRequest.Free();
            end;
          finally
            RESTClient.Free();
          end;
        finally
           outStream.Free();
        end;
      finally
         inStream.Free();
      end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 36
    Par défaut Suite
    Bonjour et merci pour votre aide

    je viens d'essayer et c'est toujours pareil

    je pense que le problème vient de l'instruction LJSONObject.AddPair('content', outStream.DataString);
    j'ai rajouté des showmessage pour suivre la valeur de LJSONObject.ToJson

    juste après LJSONObject.AddPair('prenom','marc'); la valeur de LJSONObject.ToJson affiche {"name":"MonFichier.pdf","prenom":"marc"}

    mais après le LJSONObject.AddPair('content', outStream.DataString); LJSONObject.ToJson est vide

    comment peut on passer une stream à une valeur d'une clé JSON ?

    Marc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     try
        LJSONObject := TJsonObject.Create;
        VRequest := TJsonValue.Create;
     
     
        outStream.Position := 0;
     
        Showmessage('datastring = ' + outStream.DataString);
     
        LJSONObject.AddPair('name','MonFichier.pdf');
        LJSONObject.AddPair('prenom','marc');
        ShowMessage(LJSONObject.ToJson);
     
        LJSONObject.AddPair('content', outStream.DataString);
        ShowMessage(LJSONObject.ToJson);
     
        ShowMessage(inttostr(LJSONObject.Count));
     
        RESTRequest_PostFiles.AddBody(LJSONObject);
     
     
        // convert String to JSON
        //SONObject.Parse(BytesOf(outStream.ToString), 0);
     
        // output the JSON to console as String
        //ShowMessage(LJSONObject.ToString);
      finally
     
      end;

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 001
    Par défaut
    ah oui donc c'est surement le contenu du Base64 qui ne convient pas, ayant récemment utilisé TBase64Encoding j'avais noté qu'il était différent par défaut qu'un encodage par SQL Server par exemple, du coup, j'ai juste passé 0 en paramètre au constructeur pour une ligne infinie (par défaut, il y a une limite par ligne comme dans un DFM)

    TBase64Encoding instancié localement à la place du singleton TNetEncoding.Base64 qui est pré-configuré pour les besoins de la VCL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    procedure TFYS_principale.BPostFilesClick(Sender: TObject);
    var
      inStream: TStream;
      outStream: TStream;
      RESTClient: TRESTClient;
      RESTClient: TRESTRequest;
      LJSONObject: TJSONObject;
    begin
     
      // chargement du fichier PDF dans un stream
      inStream := TFileStream.Create('c:\testpdf\test.pdf', fmOpenRead);
      try
        outStream := TStringStream.Create;
        try
         RESTClient := TRESTClient.Create(URL); // URL contient juste https://server/service/
         try
           RESTClient.ContentType := 'application/json; charset=utf-8'; // voir ce qui est nécessaire
     
            RESTRequest := TRESTRequest.Create(nil);
            try
              RESTRequest.Resource := fonction; // optionnel c'est la fonction REST, on a une une adresse https://server/service/fonction
              RESTRequest.Method := TRESTRequestMethod.rmPOST;
     
              RESTRequest.Client := RESTClient;
     
              LJSONObject := TJSONObject.Create();
              try
                LJSONObject.AddPair('name','MonFichier.pdf'); // prévoir un TEncoding.UTF8.Encode
     
                inStream.Seek(0, soBeginning);
                with TBase64Encoding.Create(0) do
                try
                  if Encode(inStream, outStream) > 0 then
                     LJSONObject.AddPair('content', outStream.DataString);
                finally
                  Free();
                end;
     
                RESTRequest.AddBody(LJSONObject);
              finally
                LJSONObject.Free();
              end;
     
              RESTRequest.Execute();
              memo.Text := RESTRequest.Response.Content; // ou Request.Response.JSONText
            finally
              RESTRequest.Free();
            end;
          finally
            RESTClient.Free();
          end;
        finally
           outStream.Free();
        end;
      finally
         inStream.Free();
      end;
    end;
    dans mon code c'est pour sauvegarder un binaire en base64 dans DB, voici les fonctions concernant l'encodage (sous fonction d'une fonction mère)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    function EncodeDummyToBase64(AVersion: Word): string;
      var
        Data: TMemoryStream;
        EncodedData: TStringStream;
      begin
        Data := TMemoryStream.Create();
        try
          Data.Write(AVersion, SizeOf(AVersion));
          if AVersion = V1 then
            EncodeDummyV1(Data);
     
          EncodedData := TStringStream.Create();
          try
            Data.Seek(0, soBeginning);
            with TBase64Encoding.Create(0) do
            try
              if Encode(Data, EncodedData) > 0 then
                Result := EncodedData.DataString;
            finally
              Free();
            end;
          finally
            EncodedData.Free();
          end;
        finally
          Data.Free();
        end;
      end;
     
    procedure DecodeDummyFromBase64(const ADataEncodedBase64: string);
      var
        EncodedData: TStringStream;
        Data: TMemoryStream;
        Version: Word;
      begin
        EncodedData := TStringStream.Create(ADataEncodedBase64, TEncoding.ANSI);
        try
          Data := TMemoryStream.Create();
          try
            with TBase64Encoding.Create(0) do
            try
              if Decode(EncodedData, Data) > 0 then
              begin
                Data.Seek(0, soBeginning);
                if (Data.Read(Version, SizeOf(V1)) = SizeOf(V1)) then
                begin
                  if Version = V1 then
                    DecodeDummyV1(Data)
                  else if Version = V0 then
                    DecodeDummyV0(Data);
                end
              end;
            finally
              Free();
            end;
          finally
            Data.Free();
          end;
        finally
          EncodedData.Free();
        end;
      end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 36
    Par défaut Suite upload d'un fichier PDF dans un RESTRequest JSON
    Merci encore pour vos remarques mais ça ne fonctionne pas

    le body du RESTRequest doit ressembler à ça :
    {
    "name": "MonFichier.pdf",
    "content": "JVBERi0xLjMNJeLjz9MNCjIzMCAwIG9iag08PC9MaW5lYXJpemVkIDEvTCAxMTI1MDAvTyAyMzIvRSA3NzUyMS9OIDIvVCAxMTIxMDcvSCBbIDEzNzEgNDg2XT4+DWVuZG9iag0gICAgICAgICAgICAgDQozMDQgMCBvYmoNPDwvRGVjb2RlUGFybXM8PC9Db2x1bW5zIDUvUHJlZGljdG9yIDEyPj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0lEWzxGRUQzRjY5MDY3OTA0OEM4RUE2RUFGQjgyQkZCNzM1Qz48QUUyNTY1RTRDOEUzN0Q0ODhEMkRBRDE2OUZGMjBCRTk+XS9JbmRleFsyMzAgMzMzXS9JbmZvIDIyOSAwIFIvTGVuZ3RoIDI0NS9QcmV2IDExMjEwOC9Sb290IDIzMSAwIFIvU2l6ZSA1NjMvVHlwZS9YUmVmL1dbMSAzIDFdPj5zdHJlYW0NCmje7NI/SgNBFMfxN7O7CcsGIlhFiGwVUiQLiRIbG29gJ6T2T+E9UmmRAyQEEVtPkC4BezsvYRphBWHd951mDrDlNB9+vHlvdmZ3rRE5EivSnqhyp9qdaiq8xBEWrF6R+9jzVtGekac4xhhnXnZTLczxlNmEPMAS//DXm3 ... etc "}


    ce qui me coince, c'est comment intégrer dans le body du RESTRequest le contenu d'un PDF converti en BASE64.
    j'encode le fichier par le code suivant et ça fonctionne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var
      inStream: TFileStream;
      outStream: TMemoryStream;
     
    etc ..
     
    // chargement du fichier PDF dans un stream
      inStream := TFileStream.Create('c:\testpdf\test.pdf', fmOpenRead);
      outStream := TMemoryStream.Create;
      // encodage en 64 bits
      TNetEncoding.Base64.Encode(inStream, outStream);
    j'obtiens bien dans le outstream mon PDF Encodé en 64Bits.

    ce que je n'arrive pas à faire, c'est l'inclure dans un TJSONObject

    J'ai essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LJSONObject.AddPair('content', outStream.DataString)
    mais visiblement ça découpe la chaine de caractères

    Merci encore pour vos réponses

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 001
    Par défaut
    Vous n'avez pas lu ma réponse !
    Vous ne faites que répéter ce qui a déjà été écrit :
    Citation Envoyé par ShaiLeTroll Voir le message
    ah oui donc c'est surement le contenu du Base64 qui ne convient pas, ayant récemment utilisé TBase64Encoding j'avais noté qu'il était différent par défaut qu'un encodage par SQL Server par exemple, du coup, j'ai juste passé 0 en paramètre au constructeur pour une ligne infinie (par défaut, il y a une limite par ligne comme dans un DFM)
    Nous faisons l'effort de fournir un code complet, nous attendons que vous preniez le temps pour le lire, l'étudier et le comprendre, c'est un minimum !
    Vous êtes tout de même sur la bonne piste, nous sommes surpris de voir que vous ne faites pas la démarche de chercher un peu plus la réponse qui est sous votre nez


    Citation Envoyé par ShaiLeTroll Voir le message

    TBase64Encoding instancié localement à la place du singleton TNetEncoding.Base64 qui est pré-configuré pour les besoins de la VCL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
     
                inStream.Seek(0, soBeginning);
                with TBase64Encoding.Create(0) do
                try
                  if Encode(inStream, outStream) > 0 then
                     LJSONObject.AddPair('content', outStream.DataString);
                finally
                  Free();
                end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 36
    Par défaut Suite upload d'un fichier PDF dans un RESTRequest JSON
    Je m'excuse platement ...
    ça fonctionne parfaitement maintenant
    la prochaine fois, promis, je lirai la réponse avec attention ...
    Merci encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Création d'un serveur FTP avec Indy et Delphi
    Par ram-0000 dans le forum Réseaux
    Réponses: 0
    Dernier message: 03/04/2013, 11h46
  2. Création d'un contrôle Winform avec Delphi pour .NET
    Par Nono40 dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 13/02/2013, 20h11
  3. création d'une base de données sous delphi avec access
    Par akilam84 dans le forum Bases de données
    Réponses: 2
    Dernier message: 23/09/2008, 19h47
  4. Création de fichier json avec PHP
    Par versus68 dans le forum Langage
    Réponses: 1
    Dernier message: 02/06/2008, 11h56
  5. Connection ou création d'une base interbase avec Delphi
    Par vincentj dans le forum Bases de données
    Réponses: 2
    Dernier message: 07/01/2005, 10h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo