Click here to Skip to main content
15,881,715 members
Articles / Desktop Programming / ATL

C++ SOAP Client for MS SOAP Toolkit 1.0 using Wire Transfer Technique

Rate me:
Please Sign up or sign in to vote.
4.67/5 (3 votes)
7 Feb 2001CPOL 95.8K   1.5K   18   5
C++ SOAP client for December 2000 release of MS SOAP Toolkit 1.0 using wire transfer technique

Requirements

Introduction

In July 2000, Microsoft released the first version of the SOAP Toolkit for Visual Studio 6.0. In September 2000, the Beta 1 of the SOAP Toolkit Version 1.0 was released. In my opinion, the most remarkable feature that was added is the SSL support. The most recent, non beta version is the version from December 2000 with bug fixes and small changes in the exposed interfaces. The purpose of this article is to demonstrate the wire transfer technique using a C++ client and ATL. Many thanks to Peter Santos.

About the Sample

MS provided, for testing purposes, the web service. The web service description can be found at the following link. The sample uses this web service and demonstrates the execution of GetStockQuote method exposed by this web service. The sample contain two methods, Connect and GetStockMethod.

Connect Method

This is the method for obtaining the service description and URI listener from the web service. These are two strings (BSTRs) that we will keep for using in GetStockMethod:

C++
long            nSuccess, item = 0;
CComVariant     varTemp;

ROPE::ISOAPPackagerPtr          packer;
CComPtr<IUnknown>               pIUnknown;
ROPE::IServiceDescriptorsPtr    pIServiceDescriptors;
ROPE::ISDEndPointInfoPtr        pISDEndPointInfo;
USES_CONVERSION;

try
{
    HRESULT hr = packer.CreateInstance( ROPE::CLSID_SOAPPackager );

    //load service description from this web service
    hr = packer->LoadServicesDescription(ROPE::icURI,
                        bstrLocation, NULL, &nSuccess);
    if( nSuccess != 1 )
        throw E_FAIL;

    //get service descriptors
    hr = packer->get_GetServiceDescriptors(ROPE::icENDPOINTINFO, &varTemp);

    pIUnknown.Attach( varTemp.pdispVal );
    pIUnknown.QueryInterface( &pIServiceDescriptors );

    //get first descriptor on the list
    VariantInit(&varTemp);
    hr = pIServiceDescriptors->get_Item(variant_t(item),&varTemp);
    pIUnknown.Detach();

    //get the endpoint(URI address) a.e. where the SOAP message will be sent
    pIUnknown.Attach( varTemp.pdispVal );
    hr = pIUnknown.QueryInterface( &pISDEndPointInfo );
    hr = pISDEndPointInfo->get_URI(&URI_LISTENER);

    //get the service description
    hr = packer->get_ServicesDescription(&bstrSrvDesc);
}
catch(...)
{
    std::cout << "Connection failure ! "<< std::endl;
    return false;
}
std::cout << "Connection successful "<< std::endl;
return true;

GetStockMethod

This is the method for calling the exposed GetStockPrice method from the web service. After the creation of a new SOAPPackager object and the loading of the service description from the string obtained from the Connect method, the payload will be created and posted (using a new WireTransfer object) to the web service and the result will be displayed:

C++
long        nSuccess;
CComBSTR    bstrRequestStruct, bstrRequestPayload, bstrResponsePayload;
CComVAriant varPrice;

ROPE::ISOAPPackagerPtr packer;
ROPE::IWireTransferPtr wireTrans;

USES_CONVERSION;

try
{
    HRESULT hr = packer.CreateInstance( ROPE::CLSID_SOAPPackager );

    //load service description using the string from previous Connect method call
    hr = packer->LoadServicesDescription(ROPE::icSTRING,
                        bstrSrvDesc, NULL, &nSuccess);
    if( nSuccess != 1 )
        throw E_FAIL;

    //seek in the service description
    //the method structure a.e. what we need to call this method
    hr = packer->GetMethodStruct(CComBSTR("GetStockQuote"), ROPE::icINPUT, &bstrRequestStruct);

    // set method name
    hr = packer->SetPayloadData(ROPE::icREQUEST, CComBSTR(""),
         CComBSTR("GetStockQuote"), bstrRequestStruct);

    //set method parameters
    hr = packer->SetParameter(  ROPE::icREQUEST, CComBSTR("Symbol"), CComVariant("MSFT") );
    hr = packer->SetParameter(  ROPE::icREQUEST,
                                CComBSTR("description"), CComVariant("any company") );

    //get the data that will be sent to web server( payload )
    hr = packer->GetPayload( ROPE::icREQUEST, &bstrRequestPayload);

    std::cout <<  W2A(bstrRequestPayload) << std::endl << std::endl;

    //post the payload
    wireTrans.CreateInstance( ROPE::CLSID_WireTransfer);
    hr = wireTrans->AddStdSOAPHeaders(URI_LISTENER,CComBSTR("GetStockQuote"),
                    bstrRequestPayload.Length());
    hr = wireTrans->PostDataToURI(URI_LISTENER, bstrRequestPayload, &bstrResponsePayload);

    std::cout <<  W2A(bstrResponsePayload) << std::endl << std::endl;

    //this is the response from service
    hr = packer->SetPayload( ROPE::icRESPONSE, bstrResponsePayload);

    //get return value
    hr = packer->GetParameter( ROPE::icRESPONSE, CComBSTR("result"), &varPrice);
    std::cout << W2A(varPrice.bstrVal) << std::endl;
}
catch(...)
{
    std::cout << "Something wrong happened !" << std::endl<< std::endl;
}

Conclusion

I hope you will find this approach useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) binaryfog.com
Canada Canada

Comments and Discussions

 
QuestionSOAP response is ? Pin
ILoveMJ18-Dec-06 2:55
ILoveMJ18-Dec-06 2:55 
QuestionHELP ME!!!why toolkit3.0 generate these bad XML for me? Pin
gxulg16-Jan-05 19:08
gxulg16-Jan-05 19:08 
Generaljava and SOAP Pin
17-May-01 0:33
suss17-May-01 0:33 
GeneralSOAP+java Pin
16-May-01 5:21
suss16-May-01 5:21 
GeneralRe: SOAP+java Pin
Catalin Hatmanu16-May-01 6:49
Catalin Hatmanu16-May-01 6:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.