public loTaxService AS "XML Web Service" * LOCAL loTaxService AS "MSSOAP.SoapClient30" * Do not remove or alter following line. It is used to support IntelliSense for your XML Web service. *__VFPWSDef__: loTaxService = https://test.afrservices.com/DataExchange/ICG/TaxService.asmx?wsdl , TaxService , TaxServiceSoap LOCAL loException, lcErrorMsg, loWSHandler TRY loWSHandler = NEWOBJECT("WSHandler",IIF(VERSION(2)=0,"",HOME()+"FFC\")+"_ws3client.vcx") loTaxService = loWSHandler.SetupClient("https://test.afrservices.com/DataExchange/ICG/TaxService.asmx?wsdl", "TaxService", "TaxServiceSoap") * Call your XML Web service here. ex: leResult = loTaxService.SomeMethod() CATCH TO loException lcErrorMsg="Error: "+TRANSFORM(loException.Errorno)+" - "+loException.Message DO CASE CASE VARTYPE(loTaxService)#"O" * Handle SOAP error connecting to web service CASE !EMPTY(loTaxService.FaultCode) * Handle SOAP error calling method lcErrorMsg=lcErrorMsg+CHR(13)+loTaxService.Detail OTHERWISE * Handle other error ENDCASE * Use for debugging purposes MESSAGEBOX(lcErrorMsg) FINALLY ENDTRYThis does appear to work in that the loTaxService object has the correct web methods available. I believe I still need to embed the credentials in the soap header. Further research dredged up this example class:
DEFINE CLASS myHeaderHandler AS custom olepublic IMPLEMENTS IHeaderHandler IN "c:\program files\common files\mssoap\binaries\mssoap30.dll" *The namespace of the header element PROTECTED HEADER_ELEMENT_NAMESPACE *The name of the header element PROTECTED HEADER_ELEMENT_NAME *The name of the user element PROTECTED USER_ELEMENT_NAME *The value of the header HeaderValue = "" *This function is used to read an incoming soap header PROTECTED FUNCTION IHeaderHandler_readHeader(par_Reader as MSSOAPLib30.ISoapReader, parHeaderNode as MSXML2.IXMLDOMNode, par_Object as Object) as Boolean IF parHeaderNode.baseName <> this.HEADER_ELEMENT_NAME OR parHeaderNode.namespaceURI <> this.HEADER_ELEMENT_NAMESPACE THEN IHeaderHandler_readHeader = .F. RETURN ENDIF this.HeaderValue = parHeaderNode.text IHeaderHandler_readHeader = .T. ENDFUNC *This function states that headers the writeHeaders function will be called PROTECTED FUNCTION IHeaderHandler_WillWriteHeaders() as Boolean IHeaderHandler_WillWriteHeaders = .T. ENDFUNC *This function is used to write an outgoing soap header PROTECTED FUNCTION IHeaderHandler_writeHeaders(pSerializer As MSSOAPLib30.SoapSerializer30, pObject as Object) pSerializer.StartHeaderElement(this.HEADER_ELEMENT_NAME, this.HEADER_ELEMENT_NAMESPACE) pSerializer.StartElement(this.HEADER_ELEMENT_NAME) pSerializer.WriteString(this.HeaderValue) pSerializer.EndElement() pSerializer.EndHeaderElement() ENDFUNC *Set the name of the header element FUNCTION SetHeaderName(HeaderName as String) this.HEADER_ELEMENT_NAME = HeaderName ENDFUNC *Set the namespace of the header element FUNCTION SetHeaderNameSpace(HeaderNameSpace as String) this.HEADER_ELEMENT_NAMESPACE = HeaderNameSpace ENDFUNC *Set the name of the user element FUNCTION SetUserElement(UserElement as String) this.USER_ELEMENT_NAME = UserElement ENDFUNC ENDDEFINE wsClient = CREATEOBJECT("MSSOAP.SOAPCLIENT30") HH = CREATEOBJECT("myHeaderHandler") HH.setheadername("SessionInfo") HH.setheadernamespace("myNameSpace") && This is a made up value but it must match the header namespace coming from HH.setuserelement("SessionId") && the serverI believe I need to instantiate one of these header handlers and set it as the handler for the web service client in the first example, then provide the correct namespace and element names. I'd like some help understanding this better before trying to hook all this together. Also, I would certainly consider alternate approaches. Is there a way I can write a client in Visual studio and just call it from Fox like a COM class? I have an example VS2005 client project provided by the guy I'm working with. maybe that's the easier way to approach this task?