Atozed Forums

Full Version: problem with post methos https - URGENT
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

I have this function 

function TFDMFE.EncodeFile(const FileName: string): AnsiString;
var
  stream: TMemoryStream;
begin
    stream := TMemoryStream.Create;
    try
      stream.LoadFromFile(filename);
      result := EncodeBase64(stream.Memory, stream.Size);
    finally
         FreeAndNil(stream);
    end;
end;

procedure TFDMFE.InviaFE(Autorizzazione, PercorsoFileXML, Credenziali, Dominio : string);
var
 lHTTP: TIdHTTP;
 lParamList: TStringList;
 Comando, RisultatoPost : string;
begin
   //************ COMANDO HTTP ********
   Comando := 'https://ws.fatturazioneelettronica.aruba.it/services/invoice/upload';
   //**********************************

   lParamList := TStringList.Create;

   Credenziali := '""';
   Dominio := '""';

   try
     lParamList.Add('"dataFile":"'+EncodeFile(PercorsoFileXML)+'"');
     lParamList.Add('"credential":'+Credenziali); // vuoti
     lParamList.Add('"domain":'+Dominio);     // vuoti

     lHTTP := TIdHTTP.Create;
     try
        lHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
        lHTTP.HandleRedirects := True;
        lHTTP.Request.CustomHeaders.FoldLines := False;
        lHTTP.Request.Accept := 'application/json';
        lHTTP.Request.CustomHeaders.Add('Authorization:Bearer ' + Autorizzazione);
        lHTTP.Request.ContentType := 'application/json';
        lHTTP.Request.CharSet := 'UTF-8';

         try
              RisultatoPost := lHTTP.Post(Comando, lParamList);
          except
            on E: EIdHTTPProtocolException do
            begin
                Memo1.Lines.Add(E.ErrorMessage);
            end;
          end;
     finally
       lHTTP.Free;
     end;

   finally
      lParamList.Free;
   end;
end;

I have this error:

{"timestamp":"2019-03-01T21:45:29.634+0000","status":400,"error":"Bad Request","message":"JSON parse error: Unexpected character ('%' (code 37)): expected a valid value (number, String, array, object, 'true', 'false' or 'null'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('%' (code 37)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n at [Source: (PushbackInputStream); line: 1, column: 2]","path":"/core-trasmissione-rest-fattura/services/invoice/upload"}


THIS IS THE DOCUMENTATION:

7.1. Upload invoice
Code:
POST /services/invoice/upload

Questo metodo deve essere utilizzato dall’OE per effettuare l’invio di una fattura già nel formato XML secondo norme AGID, ma non ancora firmata digitalmente.
HTTP request
Code:
POST /services/invoice/upload HTTP/1.1
Accept: application/json
Authorization: Bearer NLOGDVXLVaF3tzmnVPkTwpkuh7dG0i09uSCcog3u+rE=
Content-Type: application/json;charset=UTF-8

{
 "dataFile" : "dGVzdA==",
 "credential" : "",
 "domain" : ""
}


I parametri [i]"domain" e "credential" rappresentano rispettivamente il dominio e le credenziali di firma automatica se possedute dall’utente, in caso contrario lasciare tali campi vuoti.[/i]

Request headers
Name
Description

Code:
Authorization

Provisioner access token

Request fields
Path
Type
Description

Code:
dataFile

Code:
String

Dati allegato in formato encoded Base64

Code:
credential

Code:
String

Credenziali firma

Code:
domain

Code:
String

Domain firma

HTTP response
Code:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 105

{
 "errorCode" : "",
 "errorDescription" : "",
 "uploadFileName" : "IT01490810845_uxjhl.xml.p7m"
}

Response fields
Path
Type
Description

Code:
uploadFileName

Code:
String

Nome file fattura (inviato a SdI) restituito dal ws

Code:
errorCode

Code:
String

Eventuale codice di errore

Code:
errorDescription

Code:
String

Eventuale descrizione errore



thanks
You can't post JSON data using the TStrings overload of TIdHTTP.Post(). That overload is designed for posting HTML webforms, and as such will post the data in "application/x-www-webform-urlencoded" format, which will corrupt your JSON (not that you are populating the TStringList correctly for JSON anyway, because you are not). That is why you are getting a "Bad request" error from the server about unexpected '%' characters.

Since you want to post the JSON in "application/json" format, you need to use the TStream overload of TIdHTTP.Post() instead:

Code:
procedure TFDMFE.InviaFE(Autorizzazione, PercorsoFileXML, Credenziali, Dominio : string);
var
  lHTTP: TIdHTTP;
  lPostData: TStringStream;
  JSON, Comando, RisultatoPost : string;

  function EscapeForJson(const S: string): string;
  var
    I: Integer;
  begin
    Result := '';
    for I := 1 to Length(S) do
    begin
      case S[I] of
        #0..#7, #11, #14..#31:
          Result := Result + '\u' + UpperCase(IntToHex(Ord(S[I]), 4));
        #8:
          Result := Result + '\b';
        #9:
          Result := Result + '\t';
        #10:
          Result := Result + '\n';
        #12:
          Result := Result + '\f';
        #13:
          Result := Result + '\r';
        #34:
          Result := Result + '\"';
        #47:
          Result := Result + '\/';
        #92:
          Result := Result + '\\';
      else
        Result := Result + S[I];
      end;
    end;
  end;

begin
 //************ COMANDO HTTP ********
 Comando := 'https://ws.fatturazioneelettronica.aruba.it/services/invoice/upload';
 //**********************************

  JSON := '{' + sLineBreak +
    '  "dataFile" : "' + EncodeFile(PercorsoFileXML) + '",' + sLineBreak +
    '  "credential" : "' + EscapeForJson(Credenziali) + '",' + sLineBreak +
    '  "domain" : "' + EscapeForJson(Dominio) + '"' + sLineBreak +
    '}';

 lPostData := TStringStream.Create(JSON, TEncoding.UTF8);
 try
    lHTTP := TIdHTTP.Create;
    try
     lHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
      lHTTP.HandleRedirects := True;
      lHTTP.Request.CustomHeaders.FoldLines := False;
      lHTTP.Request.Accept := 'application/json';
      lHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + Autorizzazione;
      lHTTP.Request.ContentType := 'application/json';
      lHTTP.Request.CharSet := 'UTF-8';

      try
        RisultatoPost := lHTTP.Post(Comando, lPostData);
      except
        on E: EIdHTTPProtocolException do
        begin
          Memo1.Lines.Add(E.ErrorMessage);
        end;
      end;
    finally
      lHTTP.Free;
    end;
  finally
    lPostData.Free;
  end;
end;

Alternatively:

Code:
uses
  ..., System.JSON;

procedure TFDMFE.InviaFE(Autorizzazione, PercorsoFileXML, Credenziali, Dominio : string);
var
  lHTTP: TIdHTTP;
  lPostData: TStringStream;
  lJSONObj: TJSONObject;
  JSON, Comando, RisultatoPost : string;
begin
  //************ COMANDO HTTP ********
  Comando := 'https://ws.fatturazioneelettronica.aruba.it/services/invoice/upload';
  //**********************************

  lJSONObj := TJSONObject.Create;
  try
    lJSONObj.AddPair('dataFile', EncodeFile(PercorsoFileXML));
    lJSONObj.AddPair('credential', Credenziali);
    lJSONObj.AddPair('domain', Dominio);
    JSON := lJSONObj.ToJSON;
  finally
    lJSONObj.Free;
  end;

  lPostData := TStringStream.Create(JSON, TEncoding.UTF8);
  try
    lHTTP := TIdHTTP.Create;
    try
      lHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
      lHTTP.HandleRedirects := True;
      lHTTP.Request.CustomHeaders.FoldLines := False;
      lHTTP.Request.Accept := 'application/json';
      lHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + Autorizzazione;
      lHTTP.Request.ContentType := 'application/json';
      lHTTP.Request.CharSet := 'UTF-8';

      try
        RisultatoPost := lHTTP.Post(Comando, lPostData);
      except
        on E: EIdHTTPProtocolException do
        begin
          Memo1.Lines.Add(E.ErrorMessage);
        end;
      end;
    finally
      lHTTP.Free;
    end;
  finally
    lPostData.Free;
  end;
end;
Hi,
thanks
now is ok....

I have use this...

with TJSONObject.Create do
try
AddPair('dataFile', EncodeFile(PercorsoFileXML));
AddPair('credential', Credenziali);
AddPair('domain', Dominio);
lPostData.Writestring(ToJSON); // this line is changed**********************
finally
Free;
end;