Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

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

0.00/5 (No votes)
7 Feb 2001 2  
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:

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:

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here