do WsExamp2b.prg
* wsexamp2a.prg
* server side
* returns data from the VFP sample database
DEFINE CLASS TasTradeData AS Session OLEPUBLIC
? Procedure GetCustomer(tcID as String) as XMLString
???Open Database (Home(2)+"\data\testdata")
???Select * from customer where Cust_ID = tcID into cursor curCustomer
???CursorToXML("curCustomer","lcXML",1,1)
???Return Strtran(lcXML,[ encoding="Windows-1252"],"")
? EndProc
ENDDEFINE
* WsExamp2b.prg
* The client program
Local loProxy as TasTradeData web service
loProxy = CREATEOBJECT("MSSOAP.SoapClient")
loProxy.MSSoapInit("http://localhost/ws/TasTradeData.WSDL")
lcXml = loProxy.GetCustomer( "ANTON" )
XMLTOCURSOR( lcXML, "names" )
Edit
RETURN
Check this out:
This is a web service that is published on XMethods - It is very simple as it only has 1 method, but I think it shows the potential of what can be done, especially across platforms and languages. This particular web service looks to be a java based class. It simply returns the current price of any Ebay auction.
LOCAL o as ebaypricewatcher
LOCAL loWS
loWS = NEWOBJECT("Wsclient",HOME()+"ffc\_webservices.vcx")
loWS.cWSName = "ebaypricewatcher"
o = loWS.SetupClient("http://www.xmethods.net/sd/2001/EBayWatcherService.wsdl", "eBayWatcherService", "eBayWatcherPort")
DO WHILE .T.
lnKey = INKEY(3)
IF lnKey = 27
EXIT
ENDIF
* Pass ebay auction number
?o.getcurrentprice("1296041972")
ENDDO
I'm thinking about writing a simple screen that lets you set the time between checks, WAV file to play when your high limit is hit, etc. I know some people who do a lot of buying on Ebay that would probably like to have something like this. They tell me that the email notifications can be slow and having to go out and click refresh in the browser to see the price change can be very unproductive. -- Randy Jean
Looks like this web service no longer works. Always returns -1 for the price. I think all API development must go through Ebay and you have to register with them to get a token. See: http://developer.ebay.com/developercenter/soap/
Here is the VFP8 version of the eBay Price Watcher. As you can see VFP8 does not use or have the _webservices.vcx file and uses _ws3client.vcx instead.
loWSHandler = NEWOBJECT("WSHandler",IIF(VERSION(2)=0,"",HOME()+"FFC\")+"_ws3client.vcx")
loeBayWatcherPort = loWSHandler.SetupClient("http://www.xmethods.net/sd/2001/EBayWatcherService.wsdl", "eBayWatcherService", "eBayWatcherPort")
leResult = loeBayWatcherPort.getCurrentPrice(3360919892)
David LCrooks
Another one from XMethods. This one gets you 20-minutes delayed US Stock quotes:
LOCAL o, loWS
loWS = NEWOBJECT("WSHandler",HOME()+"ffc\_ws3client.vcx")
loWS.WSName = "Delayed Stock Quote"
o = loWS.SetupClient("http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl",;
"net.xmethods.services.stockquote.StockQuoteService",;
"net.xmethods.services.stockquote.StockQuotePort")
? o.getquote("MSFT")
-- Alex Feldstein
Basic Address Standardizer
Local loZipWS as zip ws
LOCAL loWS
loWS = NEWOBJECT("Wsclient",HOME()+"ffc\_webservices.vcx")
loWS.cWSName = "zip ws"
loZipWS = loWS.SetupClient("http://webservices.eraserver.net/zipcoderesolver/zipcoderesolver.asmx?WSDL", "ZipCodeResolver", "ZipCodeResolverSoap")
lcVer = loZipWS.VersionInfo()
? lcVer
lcHtmlAddr = loZipWS.CorrectedAddressHTML( "0", "8345 Newland Av", "niles", "il" )
? lcHtmlAddr
loXMLAddr = loZipWS.CorrectedAddressXML( "0", "8345 Newland Av", "niles", "il" )
* What do I do with loXMLAddr ????
* I don't know. When I examine loZipWS I see "Client: Incorrect number
* of parameters supplied for SOAP request" in the detail property. -- RandyJean
- ?CFK
Here's a repost of mine from the UT:
To VFP developers a Web service is a non visual class that has methods. Lets take this one for example
DEFINE CLASS myclass AS session
PROCEDURE GetOrderDate
LPARAMETERS tcOrderNumber
LOCAL ldReturn
ldReturn = {}
USE home(2) + "Tastrade\Data\orders.dbf"
if seek(padl(tcOrderNumber, 6), 'orders', 'order_numb')
ldReturn = order_date
endif
USE
RETURN ldReturn
ENDDEFINE
I can now call this class like this:
oClass = createobject('myclass')
?oClass.GetOrderDate(1075)
Now lets make this VFP specific class into a multi langauge COM object. I'm going to add the OLEPUBLIC keyword to the class defintion, plus, I'll use new VFP7 syntax to define what type of parameters and return values my method expects. Everything else will stay the same:
DEFINE CLASS myclass AS session OLEPUBLIC
PROCEDURE GetOrderDate(tcOrderNumber AS string) AS date
LOCAL ldReturn
ldReturn = {}
USE home(2) + "Tastrade\Data\orders.dbf"
if seek(padl(tcOrderNumber, 6), 'orders', 'order_numb')
ldReturn = order_date
endif
USE
RETURN ldReturn
ENDDEFINE
If I add this code to a project and compile the project as a DLL, I can now run my code from any COM enabled language (VB, Delphi, VFP, VBScript, ASP, ect.)
Here's how it could be called from VFP
oCOM = createobject('projectname.myclass')
?oCOM.GetOrderDate(1075)
Now, I can take my Class, and move it to the next level, Web services, by running the Web Service Publisher in VFP7. This will create some supporting files, like WSDL, and maybe an ASP page. Web services can be used by any platform that support HTTP and XML (I can't think of one that doesn't, since XML it just text with angle brackets around it < >).
When the WSDL is created, your class can now be called like this:
oWebService = CREATEOBJECT('mssoap.soapclient')
oWebService.mssoapinit('http://www.myserver.net/myclass.wsdl')
?oWebService.GetOrderDate(1075)
Anyone can call your class from anywhere in the world with an internet connection. So, if I had a URL to your WSDL file, I would call your Web Service with parameters, the class will execute completely on your computer, and the return value will be sent back to my computer, all through the internet.
Mike Helland
Anybody ever type to put variable/property persistence in web service written in VFP? i.e. VFP OLEPUBLIC class->COM->Web Service.
Check out the code segment below:
DEFINE CLASS wsSession AS SESSION OLEPUBLIC
PROTECTED _oEnv
PROTECTED isAlive
PROCEDURE Init
THIS._oEnv = .NULL.
THIS.isAlive = .F.
ENDPROC
FUNCTION checkEnv AS String
RETURN TYPE("THIS._oEnv")
ENDFUNC
FUNCTION getStatus AS String
RETURN "I'm alive. And Env. is " + TYPE("THIS._oEnv")
ENDFUNC
FUNCTION initEnv AS Boolean
THIS.isAlive = .T.
_nAppMode = APPMODE_COMSERVER
THIS._oEnv = CREATEOBJECT("_Environment")
RETURN THIS.checkHandler()
ENDFUNC
PROCEDURE cleanEnv
THIS._oEnv = null
SET CLASSLIB TO
ENDPROC
FUNCTION checkHandler AS Boolean
RETURN THIS._oEnv.isEventHandlerReady()
ENDFUNC
FUNCTION checkAlive AS Boolean
RETURN THIS.isAlive
ENDFUNC
ENDDEFINE
I've tried to put two properties "isAlive" and "_oEnv" which are logical and object type respectively. However, when I test my web service in VFP7 with the following method call sequence:
LOCAL loSession as wsSession
LOCAL loWS
loWS = NEWOBJECT("Wsclient",HOME()+"ffc\_webservices.vcx")
loWS.cWSName = "wsSession"
loSession = loWS.SetupClient("http://localhost/soap/wsSession.wsdl", "wsSession", "wsSessionSoapPort")
? loSession.getStatus()
? loSession.checkAlive()
? loSession.initEnv()
? loSession.getStatus()
? loSession.checkAlive()
? loSession.checkEnv()
loSession = NULL
It shows me:
I'm alive. And Env. is L <-- loSession.getStatus()
L <-- loSession.checkAlive()
.T. <-- loSession.initEnv()
I'm alive. And Env. is L <-- loSession.getStatus()
L <-- loSession.checkAlive()
L <-- loSession.checkEnv()
Only one conclusion here, all properties within my Session class are not persistence across methods. It's not the case when it's a COM before turning into Web service.
Is all web service behave like this? Or it's the problem of web service created by VFP?
Franco Lam
Contributors Carl Karsten, Claudio Lassala, Kevin Wright, Randy Jean, Alex Feldstein
See also: Web Services Wishful Thinking
Wiki Web Services VFPSample Code
Category Web Development Category Code Samples