FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour JSON - request then decode
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
JSON - request then decode
Posted: Mon Jul 17, 2017 10:19 PM

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

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:

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
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: JSON - request then decode
Posted: Tue Jul 18, 2017 04:47 AM
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
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: JSON - request then decode
Posted: Tue Jul 18, 2017 03:26 PM

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
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: JSON - request then decode
Posted: Tue Jul 18, 2017 10:22 PM

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

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
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 04:25 AM

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.

#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

Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 05:01 AM

If you send me your email to tim at gtstone dot com I can send you the actual values to use.

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 90
Joined: Wed Nov 07, 2007 08:56 AM
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 09:48 AM
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 (fw): Select all Collapse
DO WHILE oXMLHttp:readyState <> 4
SysRefresh()
ENDDO
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 12:43 PM
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.
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: JSON - request then decode
Posted: Wed Jul 19, 2017 07:14 PM

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
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: JSON - request then decode RESOLVED
Posted: Wed Jul 19, 2017 08:47 PM

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
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit

Continue the discussion