Question
· 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
Discussion (14)2
Log in or sign up to continue

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)

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()

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()

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.

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())
    }
}

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.

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....