我需要用VC开发一个SOAP客户端程序,请高手指点,不胜感激

解决方案 »

  1.   

    #pragma once
    #ifndef SOAP_DEBUG_CLIENT_H_INCLUDED
    #define SOAP_DEBUG_CLIENT_H_INCLUDED
    #include <iostream>
    #include <fstream>
    #include <conio.h>
    using namespace std;
    #include "StreamOnCString.h"// LOG options
    class CSoapFloppyClient
    {
    protected:
    CReadWriteStreamOnCString m_requestStream;
    CReadWriteStreamOnCString m_responseStream;
    CStringA m_strURL; SOAPCLIENT_ERROR m_errorState;public:
    CSoapFloppyClient(LPCTSTR szURL) : m_strURL(CT2A(szURL)), m_errorState(SOAPCLIENT_SUCCESS)
    {
    } ~CSoapFloppyClient() throw()
    {
    CleanupClient();
    } SOAPCLIENT_ERROR GetClientError()
    {
    return m_errorState;
    } void SetClientError(SOAPCLIENT_ERROR errorState)
    {
    m_errorState = errorState;
    }
    void CleanupClient() throw()
    {
    m_requestStream.Cleanup();
    m_responseStream.Cleanup();
    }

    IWriteStream * GetWriteStream() throw()
    {
    return &m_requestStream;
    }


    HRESULT GetReadStream(IStream **ppStream) throw()
    {
    if (ppStream == NULL)
    {
    return E_POINTER;
    } *ppStream = &m_responseStream;
    return S_OK;
    }

    HRESULT SendRequest(LPCTSTR tszAction) throw()
    {

    ATLASSERT(tszAction != NULL); LPCSTR szAction;#ifdef UNICODE
    CW2A w2aAction(tszAction);
    szAction = w2aAction;

    #else
    szAction = tszAction;
    #endif
    if( strstr(szAction, "SOAPAction:") == szAction )
    szAction += strlen("SOAPAction:"); while( *szAction == ' ')
    szAction++;
    if( !writeOutputFile( szAction ) )
    {
    cerr << _T("Error writing request file") << endl;
    return E_FAIL;
    } cout << _T("The requests was succesfully created!") << endl;
    cout << _T("Please press any key when the response is available!") << endl; getch();
    if( !loadInputFile() )
    {
    cerr << _T("Error reading response file") << endl;
    return E_FAIL;
    } return S_OK;

    }
    protected:
    bool loadInputFile()
    {
    char inputFileName[MAX_PATH];
    bool bRet = true;
    ifstream inputStream;
    const int maxURLSize = 2048;
    char szWorkBuffer[maxURLSize];

    cout << "Please specify the file containing the response:";
    cin >> inputFileName;

    inputStream.open( inputFileName); if( !inputStream.is_open() )
    {
    cerr << "ERROR - Cannot open response file :" << inputFileName << endl;
    return false;
    }
    while( !inputStream.eof() )
    {
    inputStream.get(szWorkBuffer, maxURLSize, '\0');
    HRESULT Result = m_responseStream.WriteStream(szWorkBuffer, -1, NULL);
                bRet = SUCCEEDED(Result);
                if (!bRet)
                 break;
    } inputStream.close();
    return bRet;
    } bool writeOutputFile(LPCSTR szAction)
    {
    char outputFileName[MAX_PATH];
    bool bRet = true;
    ofstream outputStream;
    const int maxURLSize = 2048;
    char szWorkBuffer[maxURLSize];
    cout << "Please specify the file to contain the request:";
    cin >> outputFileName;

    outputStream.open( outputFileName); if( !outputStream.is_open() )
    {
    cerr << "ERROR - Cannot open request file :" << outputFileName << endl;
    return false;
    } // inserting the service URL, to be used in dispatching the call to the appropriate service
    outputStream << (LPCSTR)m_strURL << endl;

    // inserting the SOAP Action, part of the SOAP request
    outputStream << szAction << endl;

    ULONG ulActualRead = 0;
    do
    {
    HRESULT Result = m_requestStream.Read( szWorkBuffer, maxURLSize - 1, &ulActualRead);
                bRet = SUCCEEDED(Result);
                if (!bRet)
                 break;
    outputStream << (LPCSTR)m_requestStream.m_str;
    }while(ulActualRead == maxURLSize - 1); outputStream.close(); return bRet;
    }};
    #endif// SOAP_DEBUG_CLIENT_H_INCLUDED
      

  2.   

    #include "stdafx.h"#include "SimpleSoapAppProxy.h"
    using namespace SimpleSoapAppService;// Include the header for the Debug client
    #include "SoapFloppyClient.h"void main()
    {

    CoInitialize(NULL); {
    BSTR bstrIn, bstrOut;

    // Instantiate the template on the debug client instead of one of the  ...Inet clients
    // Using the URL from the WSDL, which already contains Handler=Default
    CSimpleSoapAppServiceT<CSoapFloppyClient> srv; // If a different service is targetted, a call to the following should be inserted here
    // srv.SetUrl("http://...?Handler=OtherServiceName" // Everything after this line is NOT specific to the SoapDebugClient
    bstrIn = ::SysAllocString(L"User");
            ATLASSERT(bstrIn != NULL);

    HRESULT hr = srv.HelloWorld(bstrIn, &bstrOut);

    printf("Return : %d\n", hr);
    if( SUCCEEDED(hr))
    {
    printf("Result %S\n", bstrOut);
    ::SysFreeString( bstrOut);
    }

    srv.Cleanup();
    }
    CoUninitialize();
    }
      

  3.   

    下面是个控制台的样例
    Toolkit3.0 终于给出VC6的样例了,1.0只能看到VB和ASP的#include <stdio.h>#import "msxml4.dll" 
    using namespace MSXML2;#import "C:\Program Files\Common Files\MSSoap\Binaries\mssoap30.dll" \
                exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", \
                        "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")
    using namespace MSSOAPLib30;  //你机器得安装SOAP Toolkit3.0 ,1.0时,用using namespace时报错
    void Add()
    {
       ISoapSerializerPtr Serializer;
       ISoapReaderPtr Reader;
       ISoapConnectorPtr Connector;
       // Connect to the service.
       Connector.CreateInstance(__uuidof(HttpConnector30));  //HttpConnector30 失败,无法这样创建Connector,CXX0017 Error :Symbol “HttpConnector30“ not found(摇头、叹气!)
       Connector->Property["EndPointURL"] = "http://MyServer/Soap3DocSamples/DocSample1/Server/DocSample1.wsdl";  //这个当然得改成您自己的拉
       Connector->Connect();   // Begin the message.
       //Connector->Property["SoapAction"] = "uri:AddNumbers";
       Connector->Property["SoapAction"] = "http://tempuri.org/DocSample1/action/Sample1.AddNumbers";
       Connector->BeginMessage();   // Create the SoapSerializer object.
       Serializer.CreateInstance(__uuidof(SoapSerializer30));   // Connect the serializer object to the input stream of the connector object.
       Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));   // Build the SOAP Message.
       Serializer->StartEnvelope("","","");
       Serializer->StartBody("");
       Serializer->StartElement("AddNumbers","http://tempuri.org/DocSample1/message/","","");  //这是本地的Web Services,实际中要指定命名空间
       Serializer->StartElement("NumberOne","","","");
       Serializer->WriteString("5");
       Serializer->EndElement();
       Serializer->StartElement("NumberTwo","","","");
       Serializer->WriteString("10");
       Serializer->EndElement();
       Serializer->EndElement();
       Serializer->EndBody();
       Serializer->EndEnvelope();
       
       // Send the message to the XML Web service.
       Connector->EndMessage();         // Read the response.
       Reader.CreateInstance(__uuidof(SoapReader30));   // Connect the reader to the output stream of the connector object.
       Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), "");   // Display the result.
       printf("Answer: %s\n", (const char*)Reader->RpcResult->text);
        
    }int main()
    {
       CoInitialize(NULL);
       Add();
       CoUninitialize();
       return 0;
    }更改 EndPointURL 属性的值. 在URL里指定你的服务器名. OK总结一下必要的关键步骤
    1.导入类型库2.需要创建一个SoapConnector3.下一步创建SoapSerializer4.下一步把消息附加到SoapConnector的输入流5.下一步读取结果.要读取服务器的回复,客户端应用需要使用SoapReader,6.SoapReader被连接到SoapConnector输出流7.用IXMLDOMElement对象可以从SoapReader里读到服务器的回复