Written by

Integration engineer at CHRV
Question Thomas Vessiere · May 5, 2022

Post request through HTTPOuboundAdapter send empty body ( JSON format )

Hello. 

I'm trying to POST a JSON on an URL. 

But the body request arrive empty on the web service : 

[DEBUG] # 2022-05-05 15:04:32,966 # scopes founds : api
[DEBUG] # 2022-05-05 15:04:32,971 # PatientController:PostSignaletic object null

Here is the code, i tried a TONS of ways to do it but i'm still in trouble ... 

Method SendSignaletique(Token As %String)
{
    //set UrlPats = "https://app.depistagesurdite.be/externaldemo"
    
    /*set internalID = "123456789"
      set lastName = "Test"
      set firstName = "CHRV"
      set dateOfBirth = "2022-05-04"
      set gender = "1"
      set clinicId = 22
      set mothersName = "CHR VERVIERS"
      set address = "Rue du parc , 29"
      set postalCode = 4800
      set place ="Verviers"
      set telephone1 = "087212824"*/
      
    try
    {
        set JsonArray = ##class(%DynamicArray).%New()
        set SignaletiquePat = ##class(%DynamicObject).%New()
        
        set SignaletiquePat.internalID = "050522001"
        set SignaletiquePat.lastName = "Tata"
        set SignaletiquePat.firstName = "Silva"
        set SignaletiquePat.dateOfBirth = "05/05/2022"
        set SignaletiquePat.gender = "1"
        set SignaletiquePat.clinicId = 22
        set SignaletiquePat.mothersName = "Anne Dede"
        set SignaletiquePat.address = "Rue des prés, 50"
        set SignaletiquePat.postalCode = "4620"
        set SignaletiquePat.place = "fléron"
        set SignaletiquePat.telephone1 = "0499998855"
        
        set JsonArray."0" = SignaletiquePat
        
        set JsonArrayOBJ = JsonArray.%ToJSON()
        
        $$$TRACE("Json : " _JsonArrayOBJ)
        
        set HTTPRequestPat = ##class(%Net.HttpRequest).%New()
      
          set HTTPRequestPat.ContentType = "application/json"
        
        Do HTTPRequestPat.SetHeader("Authorization","Bearer "_Token)
          Do HTTPRequestPat.EntityBody.Write(JsonArrayOBJ) // like this ? didnt work
          set ..Adapter.HTTPServer = "185.36.164.222"
          set ..Adapter.URL = UrlPats_"/api/patient/signaletic"
        set st = ..Adapter.SendFormDataURL(..Adapter.URL,.callResponsePat,"POST",HTTPRequestPat,,JsonArrayOBJ) // not working too....
      
          #dim callResponsePat as %Net.HttpResponse
          set dynamicObject = {}.%FromJSON(callResponsePat.Data)
          set JsonString = dynamicObject.%ToJSON()
          
          $$$TRACE("return : " _ JsonString)
          
          set Iterator = dynamicObject.%GetIterator()
                
          While Iterator.%GetNext(.key,.val)
          {
              if (key = "Message")
              {
                  if (val = "An Error as Occured.")
                  {
                      $$$TRACE("Erreur : "_ val)
                      
                  }
                  else
                  {
                      $$$TRACE("pas d'erreur : " _val)
                  }
              }
          
          }
          
        
    }
    catch ex
    {
        $$$TRACE("Error while sending datas: "_ex.DisplayString())
    }
}

Here are the logs : 

Trace 2022-05-05 16:34:14.363 END 108271 
Trace 2022-05-05 16:34:14.363 ERROR: Une erreur s’est produite.  108270 
Trace 2022-05-05 16:34:14.363 JSON return : {"Message":"Une erreur s’est produite."}  108269 
Trace 2022-05-05 16:34:14.363 HTTP status : 500  
Trace 2022-05-05 16:34:14.300 Json That need to be send : [{"internalID":"050522001","lastName":"Tata","firstName":"Silva","dateOfBirth":"05/05/2022","gender":"1","clinicId":22,"mothersName":"Anne Dede","address":"XXXX","postalCode":"XXXX","place":"XXXX","telephone1":"XXXXXX"}] 

Do you have any ideas ? 

Thanks you.

Vessiere Thomas.

Product version: IRIS 2021.2

Comments

Marc Mundt · May 5, 2022

Try removing the JsonArayOBJ argument from your call to SendFormDataURL.

set st = ..Adapter.SendFormDataURL(..Adapter.URL,.callResponsePat,"POST",HTTPRequestPat)
0
Thomas Vessiere  May 5, 2022 to Marc Mundt

Hi i think i already tried and it didnt work

0
Craig Regester · May 5, 2022

Your code:

Do HTTPRequestPat.EntityBody.Write(JsonArrayOBJ) // like this ? didnt work
          set ..Adapter.HTTPServer = "185.36.164.222"
          set ..Adapter.URL = UrlPats_"/api/patient/signaletic"
        set st = ..Adapter.SendFormDataURL(..Adapter.URL,.callResponsePat,"POST",HTTPRequestPat,,JsonArrayOBJ)

Try this instead:

Set json=JSONArrayOBJ.%ToJSON()
Do HTTPRequestPat.EntityBody.Write(json)
set ..Adapter.HTTPServer = "185.36.164.222"
set ..Adapter.URL = UrlPats_"/api/patient/signaletic"
set st = ..Adapter.SendFormDataURL(..Adapter.URL,.callResponsePat,"POST",HTTPRequestPat)
0
Thomas Vessiere  May 5, 2022 to Craig Regester

Hi.

Its already a Json : 
 

set SignaletiquePat.internalID = "050522001"
        set SignaletiquePat.lastName = "Tata"
        set SignaletiquePat.firstName = "Silva"
        set SignaletiquePat.dateOfBirth = "05/05/2022"
        set SignaletiquePat.gender = "1"
        set SignaletiquePat.clinicId = 22
        set SignaletiquePat.mothersName = "Anne Dede"
        set SignaletiquePat.address = "Rue des prés, 50"
        set SignaletiquePat.postalCode = "4620"
        set SignaletiquePat.place = "fléron"
        set SignaletiquePat.telephone1 = "0499998855"
        
        set JsonArray."0" = SignaletiquePat
        
        set JsonArrayOBJ = JsonArray.%ToJSON()
0
Craig Regester  May 5, 2022 to Thomas Vessiere

Apologies! Missed that line earlier! Your method of making the JSON is different than how I do it though - and execute it successfully - so could try this? 

set JsonArray = []
set SignaletiquePat = {}
        
set SignaletiquePat.internalID = "050522001"
set SignaletiquePat.lastName = "Tata"
set SignaletiquePat.firstName = "Silva"
set SignaletiquePat.dateOfBirth = "05/05/2022"
set SignaletiquePat.gender = "1"
set SignaletiquePat.clinicId = 22
set SignaletiquePat.mothersName = "Anne Dede"
set SignaletiquePat.address = "Rue des prés, 50"
set SignaletiquePat.postalCode = "4620"
set SignaletiquePat.place = "fléron"
set SignaletiquePat.telephone1 = "0499998855"

Do JsonArray.%Push(SignaletiquePat)
set JsonArrayOBJ = JsonArray.%ToJSON()
0
Thomas Vessiere  May 5, 2022 to Craig Regester

Thanks. I did it but it didnt work :/

0
David Hockenbroch · May 5, 2022

Methods that return a %Status don't automatically throw an exception. You have to check if the %Status is an error and throw it yourself. After your SendFormDataURL call, you might want to add the following and see if that gives you any more information:

if $$$ISERR(st) {
  throw ##class(%Exception.StatusException).CreateFromStatus(st)
}

However given that the HTTP status of the response is a 500 (an internal server error) there may also be a problem on that end.

0
Thomas Vessiere  May 5, 2022 to David Hockenbroch

Ok i will try with a check of an error. 

However the webservice provider told me he got an empty request everytime... 

0
Thomas Vessiere  May 5, 2022 to Thomas Vessiere

Same error : HTTP 500 from the server... I guess its a empty body request again :

Here is the update code : 

Method SendSignaletique(Token As %String)
{
    set UrlPats = "https://app.depistagesurdite.be/externaldemo"
    
    /*set internalID = "123456789"
      set lastName = "Test"
      set firstName = "CHRV"
      set dateOfBirth = "2022-05-04"
      set gender = "1"
      set clinicId = 22
      set mothersName = "CHR VERVIERS"
      set address = "Rue du parc , 29"
      set postalCode = 4800
      set place ="Verviers"
      set telephone1 = "087212824"*/
      
    try
    {
        set JsonArray = []
        set SignaletiquePat = {}
        
        set SignaletiquePat.internalID = "050522001"
        set SignaletiquePat.lastName = "Tata"
        set SignaletiquePat.firstName = "Silva"
        set SignaletiquePat.dateOfBirth = "05/05/2022"
        set SignaletiquePat.gender = "1"
        set SignaletiquePat.clinicId = 22
        set SignaletiquePat.mothersName = "Anne Dede"
        set SignaletiquePat.address = "Rue des prés, 50"
        set SignaletiquePat.postalCode = "4620"
        set SignaletiquePat.place = "fléron"
        set SignaletiquePat.telephone1 = "0499998855"
        
        Do JsonArray.%Push(SignaletiquePat)
        
        set JsonArrayOBJ = JsonArray.%ToJSON()
        
        $$$TRACE("Json signalétique patient : " _JsonArrayOBJ)
        
        set HTTPRequestPat = ##class(%Net.HttpRequest).%New()
      
          set HTTPRequestPat.ContentType = "application/json"
        
        Do HTTPRequestPat.SetHeader("Authorization","Bearer "_Token)
          Do HTTPRequestPat.EntityBody.Write(JsonArrayOBJ)
          set ..Adapter.URL = UrlPats_"/api/patient/signaletic"
        set st = ..Adapter.SendFormDataURL(..Adapter.URL,.callResponsePat,"POST",HTTPRequestPat)
        
        if ($$$ISERR(st))
        {
            throw ##class(%Exception.StatusException).CreateFromStatus(st)
        }
      
          #dim callResponsePat as %Net.HttpResponse
          set dynamicObject = {}.%FromJSON(callResponsePat.Data)
          $$$TRACE("HTTP status : "_ callResponsePat.StatusCode)
          set JsonString = dynamicObject.%ToJSON()
          
          $$$TRACE("retour ajout patient : " _ JsonString)
          
          set Iterator = dynamicObject.%GetIterator()
                
          While Iterator.%GetNext(.key,.val)
          {
              if (key = "Message")
              {
                  if (val = "Une erreur s’est produite.")
                  {
                      $$$TRACE("Erreur : "_ val)
                      
                  }
                  else
                  {
                      $$$TRACE("pas d'erreur : " _val)
                  }
              }
          
          }
          
        
    }
    catch ex
    {
        $$$TRACE("Erreur lors de l'envoi de la signalétique : "_ex.DisplayString())
    }
}
0
Thomas Vessiere  May 5, 2022 to Thomas Vessiere

My Body is not empty..... i dont know anymore lol.

0
Craig Regester  May 6, 2022 to Thomas Vessiere

Sounds like the vendor is giving you bad information then. They need to be producing better error output on their side instead of just {'Message': 'An error has occurred.' }

Likely something in the formatting of what of the fields in the JSON package is wrong - incorrect field name or bad value - but without some better error messages from the vendor or more guidance from their end, you're kind of stuck.

0
Thomas Vessiere  May 9, 2022 to Craig Regester

Hey ! 

I found what was the problem.... Look a this, i used Postman as proxy for my request. 

I found this issue with ''é" 

Then i replace "é" with "e" and it worked ! 

Do you know if studio has spécial encoding character ? 

How can i fix this ?

Thanks.

0
Thomas Vessiere  May 9, 2022 to Thomas Vessiere

Or is this the %ToJSON() that failed to translate correctly ? 

0
Thomas Vessiere  May 9, 2022 to Thomas Vessiere

Solved.

Fixed with ZCONVERT : 

        set SignaletiquePat.internalID = $ZCONVERT("050522001","O","UTF8")
        set SignaletiquePat.lastName = $ZCONVERT("Tata","O","UTF8")
        set SignaletiquePat.firstName = $ZCONVERT("Silva","O","UTF8")
        set SignaletiquePat.dateOfBirth = $ZCONVERT("05/05/2022","O","UTF8")
        set SignaletiquePat.gender = "1"
        set SignaletiquePat.clinicId = 22
        set SignaletiquePat.mothersName = $ZCONVERT("Anne Dede","O","UTF8")
        set SignaletiquePat.address = $ZCONVERT("Rue des prés, 50","O","UTF8")
        set SignaletiquePat.postalCode = "4620"
        set SignaletiquePat.place = $ZCONVERT("Fléron","O","UTF8")
        set SignaletiquePat.telephone1 = $ZCONVERT("0499998855","O","UTF8")

Like the doc said for .%ToJSON : 

NOTE: RFC 7159 specifies that the default encoding for JSON values uses UTF-8. When writing a stream containing 8-bit characters this implies that it may be necessary to explicitly convert individual values via a call to $ZCONVERT (e.g. $zcvt(value,"O","UTF8") ) or entire streams by setting the TranslateTable attribute of the stream to "UTF8"

https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic…

0