Wiki Home

Web Service Examples


Namespace: WIN_COM_API

Can anyone take a look at the following wsdl and tell me why I can't register it using VFP8 taskpane? I get a very strange error.
http://63.87.171.121/axis/services/erx?wsdl
-- Randy Jean

it's an invalid WSDL, as Element is a key word

Interesting... if you go to http://www.mgateway.com/wsdlClient.htm and pass it this URL it validates just fine....

what would I do to try to register it?
Task Pane, XML Web Services, Register an XML Web Service

Task Pane, XML Web Services gives me an empty window, no Register options. (my system is getting more and more freaky...)
Check the platform being used by your ISP. The ISAPI listener for SOAP server is currently not supported in Windows 2003. http://support.microsoft.com/default.aspx?scid=KB;EN-US;811215 This isn't just a VFP issue -- it affects all Web Services deployed on Windows 2003 with the SOAP toolkit.
- David TAnderson
That's interesting, especially since ISAPI is recommended over ASP methods for speed, etc. Did MS just shoot themselves in the foot again? Or did they just shoot us in the head? -- Randy Jean
The statement in that MS article that says ISAPI is faster than the ASP listener for VFP Web Services is pretty ridiculous. After all, the ASP dll being used is also ISAPI!! It's not using VB Scripting which is where I believe they think it would slow down??
Install the SOAP tool kit. You can find it on the VFP7 cd: \soaptoolkit\soapsdk.msi or somewhere on microsoft.com.
Hey, all of this is real great if everyone used their development box (ie. localhost) as their web server. I have a VFP8 COM object published as a web service on localhost and it works great. Now, I want to move this to an actual server that can be accessed from the web. I'm about ready to scream. HTF do I do this? I've installed Soap 3.0, VFP8 runtime, registered my COM object, created the virtual IIS folder, changed the location URL information in WSDL, etc., etc. I tested the COM object on the server and it's working fine. I can register and get to the WSDL from my local machine and it registers fine. However, it all blows up when I try to call it and it makes absolutetly no friggin sense.

Here is what I am getting:
OLE Dispatch Error code 0 from client: client: An unanticipated error occurred during the processing of this request. HRESULT=0x800A13BE - Client : Sending the Soap message failed or no recognizable response was received. HRESULT=0x800A13BE - Client: unspecified client error. HRESULT=0x800A13BE.

Replace any occurences of "localhost" in your WSDL file with the name of the real host. Oh, I've been burned by this...-- Steven Black

Thanks Steve. (notice I did say I changed the location in my WSDL)
I found the answer out in Google Newsgroups and you won't believe how obscure. I had done everything right. Turned out to be an IIS/ISAPI issue. I'm posting here to hopefully save others hours of frustration.

First, I'll refer you to an MS site that explains some of the steps:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsoap/html/soap_faq.asp?frame=true

Click on "Why doesn't the ISAPI work on my virtual root?"

This explains mapping .wsdl to the soap DLL. Why I had to do this on the server, no idea. I compared my virtual root IIS settings on my local box and it does not have .wsdl mapped anywhere, but everything works fine. The other interesting thing is that there is a Browse button to locate the DLL. However, the field that accepts the returned path does not support spaces, so you must use the 8 character path names. On my server it was: C:\PROGRA~1\COMMON~1\MSSOAP\BINARIES\SOAPIS30.DLL

Hope this helps someone else.

-- Randy Jean

Actually, the .wsdl mapping WAS on my local box but under the virtual directory of my web service and NOT the root virtual directory. Something must have put it there... Must have been the Web Service Publishing Wizard. -- Randy Jean

I was unable to use SOAP V2 and V3 web services on a Windows 2000 Server (I couldn't even access the WSDL file on my server in IE using http://server/vdir/wsdlfile.wsdl), until I followed instructions discussed in this MSKB article: http://support.microsoft.com/default.aspx?scid=kb;enus;q315158. It doesn't sound like it is related, but it sure was for me. Hope this can save others a week of real SOAP-frustration. - Eric Den Doop
Example #1: Get a list of companies that provide web servicies.
LOCAL oProxy
	
oProxy = CREATEOBJECT("MSSOAP.SoapClient")
oProxy.MSSoapInit("http://www.foxcentral.net/foxcentral.wsdl")

lcXML =  oProxy.GetProviders()
? lcXml
XMLTOCURSOR(lcXML,"xproviders",0)
BROWSE

RELEASE oProxy

Yea, I just stole this from foxcentral.net, but it took me some doing to find it, so here it is. I boiled it down to make it even simpler.

When running the example on Windows Nt4, I get an error:
Unknown com status code.
Any suggestions? I installed the soap toolkit and so on as
per the Foxpro Documentation guide! Gan Gounden

Are you running through a Proxy Server. I have the same problem connecting to Fox Central through Win Gate on my W2K laptp, but it works fine on a direct modem connection. -- Kevin Wright

I see that when the returned text contains a high ASCII (>127) character. Is there any way to check the direct return value before SOAP tries to process the XML package? -- Ed Leafe
Example #2: Both client and server sides.

  • install/start IIS
  • put wsexamp2a.prg and wsexamp2b.prg in c:\temp\wsexamp2 (or where ever you want)
  • Build Project wsexamp2a from wsexamp2a.prg
  • BUILD MTDLL wsexamp2a FROM wsexamp2a
  • modify project wsexamp2a and run the Web Services Wizard to publish wsexamp2.dll (the wizard will use the current project as defaults). Or HowToInstallAWebService
  • 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 website development.

    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
  • ( Topic last updated: 2012.02.20 04:48:26 AM )