JSON - request then decode

Post Reply
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

JSON - request then decode

Post by TimStone »

There was an discussion posted earlier that handled downloading a known JSON file and decoding it. Here is the code that was suggested:

Code: Select all

function Main()

   local odoc  := CreateObject( "MSXML2.DOMDocument" )
   local ohttp := CreateObject( "MSXML2.XMLHTTP" )
   local strret

   ohttp:Open( "GET" ,"http://www.w3schools.com/angular/customers.php", .F. )
   ohttp:SetRequestHeader( "Accept"        , "application/xml")
   ohttp:SetRequestHeader( "Content-Type" ,"application/json" )
   oDoc:async := .f.
   oDoc:LoadXml('<?xml version=""1.0"" encoding=""utf-8""?>')
   ohttp:Send(oDoc:xml)
   strret := alltrim(ohttp:responseText)

   ? strret

   StrToHashArray( StrRet )

return nil

function StrToHashArray( cStr )

   local hHash, aHash
   cStr  := CharRepl( "[]", RangeRem( 1, 31, cStr ), "{}" )
   do while '" :' $ cStr
      StrTran( cStr, '" :', '":' )
   enddo
   cStr  := StrTran( cStr, '":', '"=>' )

   hHash := &cStr
   aHash := HGetValueAt( hHash, 1 )
   xbrowser aHash setup ( obrw:autofit(), oBrw:bRClicked := { |r,c,f,o| o:ToDbf( "download.dbf", nil, nil, .t. ) } )
return nil
 
My problem is a bit different. I need to send a request to a defined website, and then read the result.

The sending statement is in the format:

Code: Select all

oHttp:=TIpClientHttp():new("https://testserver.com/data/1", .F. )
cJson := '{"partid":"147A964","productDataid":"PR123","locationid":"10000"}'
cRet := ""

IF .NOT. oHttp:open()
   MsgAlert( "Connection error:", oHttp:lastErrorMessage( ) )
ELSE
  oHttp:Post( cJson)
  cRet :=  oHttp:readAll( )
  oHttp:close()
ENDIF

 nFileHandle := FCreate( "retdata.txt" ) 
 FWrite( nFileHandle, cRet )
 FClose( nFileHandle )
 
And the response should be a JSON string. However, I get no data back. I'll worry about parsing the data when I get a return string, but at this point, it appears JSON may not like the TIP Harbour control. With the example posted on JSON decoding previously, the approach was a bit different. I'd appreciate it if someone has some alternative approaches on how I should be handling this request / response sequence.

Thanks so much.

Tim

For XML data I have been using
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: JSON - request then decode

Post by anserkk »

Code: Select all

oHttp:= CreateObject("Microsoft.XMLHTTP")
cUrl = "https://testserver.com/data/1"
   
oHttp:Open( "PUT", cUrl, .F.)
oHttp:setRequestHeader( "Content-type", "text/json" )

cJson := {"partid":"147A964","productDataid":"PR123","locationid":"10000"}   
// Try the next line too, I am not sure.
// cJson := '{"partid":"147A964","productDataid":"PR123","locationid":"10000"}'

oHttp:Send(cJson)
   
?  oHttp:Status
? oHttp:StatusText
? oHttp:responseText
   
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: JSON - request then decode

Post by TimStone »

It returns Status 405, StatusText "Method not allowed" and there is no response text.

A web search showed that this will occur if the JSON server does not accept PUT and requires a GET. So I made that change.

Now I get 415 Unsupported media type ....

Tim
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: JSON - request then decode

Post by TimStone »

Based on what the company says, and your method, here is the function code:

Code: Select all

FUNCTION ViewCFXServices3(  )

    LOCAL oHttp := CreateObject("Microsoft.XMLHTTP")
    LOCAL cUrl := "https://testserver.com/data/1"
       
    oHttp:Open( "POST", cUrl, .F.)
    ohttp:SetRequestHeader( "Accept", "application/json")
    oHttp:setRequestHeader( "Content-type", "applicationn/json" )

    cJson := '{"partID":"ABC123","productDataId":"CAT001","locationId":"10000"}'
    
    oHttp:Send(cJson)
       
    ? oHttp:Status
    ? oHttp:StatusText
    ? oHttp:responseText

RETURN NIL
 
Using the ARC add in for Google Chrome, the cJson string sent to that server with "application/json" does return the data.

Using this method, the status is 415, the StatusText is "Unsopported Media Type", and there is no responseText

Thoughts from ANYONE on where I go from here ?

Tim
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: JSON - request then decode

Post by anserkk »

Please try the following code.

Please note that depending on the documentation from your Web-api service provider, you may have to change the values in the variable cContentType. Depending on the documentation, you may also have to try using GET, PUT, POST methods while opening the URL. For me POST is working fine to send a JSON content to one of my servers and the server is returning me response in JSON format. I believe that it depends on how the Server is configured, not sure. If the server requires authentication, then that too should be dealt with. Provision for Authorization is also there in the sample code that I have provided. I assume that the URL https://testserver.com/data/1 is a dummy. When I tried that URL it is giving me 404 error.

Code: Select all

#include "Fivewin.ch"
//----------------------------------//
Function Main()

    LOCAL aHash := hash()
    LOCAL cJson,cContentType:="",cAuthorization:=""
    
    ahash["partID"] = "ABC123"
    ahash["productDataId"] = "CAT001"
    ahash["locationId"] = "10000"

    cJson := hb_jsonEncode(ahash,.f.)
    cContentType:="application/json"
    SendPostToUrl( "https://testserver.com/data/1", cJson, cContentType, cAuthorization  ) 
Return


//---------------------------------------------------------------------//
Function SendPostToUrl( cUrl, cParams,cContentType,cAuthorization )
    Local oOle,cRet:='',uRet
    default cContentType:="application/x-www-form-urlencoded"
    default cAuthorization:=""
    Try
        oOle := CreateObject( 'MSXML2.XMLHTTP' )
    Catch
        oOle := CreateObject( 'Microsoft.XMLHTTP' )
    End
    oOle:Open( 'POST', cUrl, .f. )
    
    oOle:SetRequestHeader( "Content-Type",cContentType)
    if !empty(cAuthorization)
        oOle:SetRequestHeader( "Authorization",cAuthorization)
    end if
    
    oOle:Send( cParams )
    SysRefresh()
    
    #ifdef __XHARBOUR__
        cRet := oOle:ResponseBody
    #else
        MsgInfo(oOle:ResponseBody)
        cRet:=""
        hb_jsonDecode(oOle:ResponseBody,@cRet)
        xbrowser cRet
    #endif
Return cRet
Regards

Anser
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: JSON - request then decode

Post by TimStone »

If you send me your email to tim at gtstone dot com I can send you the actual values to use.
Last edited by TimStone on Wed Jul 19, 2017 4:09 pm, edited 1 time in total.
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
Patrizio
Posts: 90
Joined: Wed Nov 07, 2007 8:56 am
Location: Italy
Contact:

Re: JSON - request then decode

Post by Patrizio »

TimStone wrote:It returns Status 405, StatusText "Method not allowed" and there is no response text.

A web search showed that this will occur if the JSON server does not accept PUT and requires a GET. So I made that change.

Now I get 415 Unsupported media type ....

Tim
I got the same error with an asynchronous webservice, did you try to put such a cycle between the send and the responsetext?

Code: Select all

DO WHILE oXMLHttp:readyState <> 4
SysRefresh()
ENDDO
 
User avatar
anserkk
Posts: 1280
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: JSON - request then decode

Post by anserkk »

TimStone wrote:If you send me your email to tim at gtstone dot com I can send you the actual values to use.
anserkk at gmail.com

I am away from my work computer, may be I can try it out tomorrow.
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: JSON - request then decode

Post by TimStone »

Yes, I did try putting in a delay before looking at the response, but that does not help.

I should note that I building this with FWH 17.06, Harbour, and MSVC++ 2017.

For XML I am using tIPHTTPClient class with no problems, but JSON seems to be unhappy ....

Tim
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
User avatar
TimStone
Posts: 2536
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA
Contact:

Re: JSON - request then decode RESOLVED

Post by TimStone »

OK ... so after all that, the process is actually quite simple, except when I added an extra n to the word application when stating the header setting for content.

Now I'm successfully implementing the call and receiving the data. I only looked at that for hours and did not see the spelling error.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
Post Reply