If you are writing a server-side application (such as an ISAPI DLL or a COM DLL to be loaded on the server side), and need to invoke a XML Web Service, you can use MSXML ServerXMLHTTP component.
The following sample C++ application illustrates using MSXML ServerXMLHTTP to invoke a .NET Web Service, either by sending HTTP GET request, or HTTP POST request, or posting SOAP and processing the SOAP response.
This sample application invokes the Weather Info XML Web Service to get the detailed weather information for any given valid US zip code.
The header file (ServerXMLHTTP1.h):
#ifndef _SERVERXMLHTTP1_H_#define _SERVERXMLHTTP1_H_#include <atlbase.h>#import <msxml4.dll> named_guidsusing namespace MSXML2;#define CHECK_HR(hr) { if (FAILED(hr)) { throw -1; } }// --------------------------------------------------------static const TCHAR* const g_lpszGetURL = _T("http://www.ejse.com/WeatherService/Service.asmx/GetWeatherInfo?zipCode=%s");// --------------------------------------------------------static const TCHAR* const g_lpszPostURL = _T("http://www.ejse.com/WeatherService/Service.asmx/GetWeatherInfo");// --------------------------------------------------------static const TCHAR* const g_lpszSOAPEndpointURL = _T("http://www.ejse.com/WeatherService/Service.asmx");static const TCHAR* const g_lpszSOAPAction = _T("http://ejse.com/WeatherService/GetWeatherInfo");static const TCHAR* const g_lpszSOAPReq = _T("<?xml version='1.0' encoding='utf-8'?> " "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " " xmlns:xsd='http://www.w3.org/2001/XMLSchema' " " xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>" " <soap:Body>" " <GetWeatherInfo xmlns='http://ejse.com/WeatherService/'>" " <zipCode>%s</zipCode>" " </GetWeatherInfo>" " </soap:Body>" "</soap:Envelope>");// --------------------------------------------------------static const TCHAR* const g_lpszXPathSelNS = _T("xmlns:ns1='http://ejse.com/WeatherService/'");// --------------------------------------------------------//TODO: Move to resource filestatic const TCHAR* const g_lpszOutputMsg = _T("Weather Information - Last Updated %s/n/n" "/tLocation: %s (%s)/n/tTemprature: %s/n/tForecast: %s/n/t" "Visibility: %s/n/tHumidity: %s/n/tPressure: %s/n");// --------------------------------------------------------#endif // _SERVERXMLHTTP1_H_
The source code file (ServerXMLHTTP1.cpp)
#include "stdafx.h"#include "ServerXMLHTTP1.h"// Utility functionvoid GetXPathExprValue(CComQIPtr<IXMLDOMDocument2> &spResponseXMLDoc, LPCTSTR lpszXPathExpr, LPSTR lpszResultValue){ USES_CONVERSION; CComPtr <IXMLDOMNode> spResultNode; spResultNode = spResponseXMLDoc->selectSingleNode(_bstr_t(lpszXPathExpr)); if(spResultNode.p != NULL) _tcscpy(lpszResultValue, W2A(_bstr_t(spResultNode->nodeTypedValue))); }//------------------------------------------------------------------------------// Function uses ServerXMLHTTP to send a GET/POST/SOAP request to a .NET Web Services,// and then uses MSXML DOM to process the response XML text.// // Illustrates calling a .NET Web Service either by sending a GET request,// or a HTTP POST or by using the SOAP method.//// iMethod parameter:// 0 : (Default) HTTP GET// 1 : HTTP POST// 2 : SOAP//------------------------------------------------------------------------------void CallWebService(LPCTSTR szZipCode, int iMethod = 0){ float fTemprature = -999; USES_CONVERSION; // Create an instance of ServerXMLHTTP Class CComPtr<IServerXMLHTTPRequest> spServerXMLHTTP1; HRESULT hr = spServerXMLHTTP1.CoCreateInstance(CLSID_ServerXMLHTTP40); CHECK_HR(hr); TCHAR szGetURL[MAX_PATH*2]={0}; TCHAR szPostValue[MAX_PATH*2]={0}; TCHAR szSOAPReq[MAX_PATH*2]={0}; int iPostDataLen =0; TCHAR szDataLen[10]={0}; switch(iMethod) { case 0: // HTTP GET sprintf(szGetURL, g_lpszGetURL, szZipCode); // Initialize the Synchronous HTTP GET request hr = spServerXMLHTTP1->open(_bstr_t(_T("GET")), szGetURL, VARIANT_FALSE); CHECK_HR(hr); // Send the HTTP GET request hr = spServerXMLHTTP1->send(); CHECK_HR(hr); break; case 1: // HTTP POST _tcscpy(szPostValue, _T("zipCode=")); _tcscat(szPostValue, szZipCode); iPostDataLen = _tcslen(szPostValue); itoa(iPostDataLen, szDataLen, 10); // Initialize the Synchronous HTTP GET request hr = spServerXMLHTTP1->open(_bstr_t(_T("POST")), g_lpszPostURL, VARIANT_FALSE); CHECK_HR(hr); spServerXMLHTTP1->setRequestHeader(_T("Content-Type"), _T("application/x-www-form-urlencoded")); spServerXMLHTTP1->setRequestHeader(_T("Content-Length"), szDataLen); // Send the HTTP POST request, along with the SOAP request envelope text hr = spServerXMLHTTP1->send(szPostValue); CHECK_HR(hr); break; case 2: // SOAP sprintf(szSOAPReq, g_lpszSOAPReq, szZipCode); hr = spServerXMLHTTP1->open(_bstr_t(_T("POST")), g_lpszSOAPEndpointURL, VARIANT_FALSE); CHECK_HR(hr); // Set the required SOAPAction and Content-Type headers hr = spServerXMLHTTP1->setRequestHeader(_T("SOAPAction"), g_lpszSOAPAction); CHECK_HR(hr); hr = spServerXMLHTTP1->setRequestHeader(_bstr_t(_T("Content-Type")), _bstr_t(_T("text/xml"))); CHECK_HR(hr); // Send the POST request, along with the SOAP request envelope text hr = spServerXMLHTTP1->send(_bstr_t(szSOAPReq)); CHECK_HR(hr); break; } if(200 == spServerXMLHTTP1->status) //Success { // using MSXML DOM to process the response XML text CComQIPtr <IXMLDOMDocument2> spResponseXMLDoc; spResponseXMLDoc = spServerXMLHTTP1->responseXML; spResponseXMLDoc->setProperty(_bstr_t(_T("SelectionNamespaces")), g_lpszXPathSelNS); TCHAR szLastUpdated[MAX_PATH] = {0}; TCHAR szLocation[MAX_PATH] = {0}; TCHAR szReportedAt[MAX_PATH] = {0}; TCHAR szTemprature[MAX_PATH] = {0}; TCHAR szForecast[MAX_PATH] = {0}; TCHAR szVisibility[MAX_PATH] = {0}; TCHAR szHumidity[MAX_PATH] = {0}; TCHAR szPressure[MAX_PATH] = {0}; GetXPathExprValue(spResponseXMLDoc, _T("//ns1:LastUpdated"), szLastUpdated); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:Location"), szLocation); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:ReportedAt"), szReportedAt); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:Temprature"), szTemprature); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:Forecast"), szForecast); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:Visibility"), szVisibility); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:Humidity"), szHumidity); GetXPathExprValue(spResponseXMLDoc, _T("//ns1:Pressure"), szPressure); printf(g_lpszOutputMsg, szLastUpdated, szReportedAt, szLocation, szTemprature, szForecast, szVisibility, szHumidity, szPressure); } else { printf(_T("/nError: %s/n"), W2A(spServerXMLHTTP1->statusText)); }}// main, The entry point functionint main(int argc, char* argv[]){ if(argc < 2) {//insufficient parameters printf(_T("/nServerXMLHTTP1.exe: Sample Web Service client to get " " the weather information for a valid given U.S. zipcode/n")); printf(_T("/nUsage:/tServerXMLHTTP1.exe <US_Zipcode> [<Method (0=GET, 1=POST, 2=SOAP)>]/n" "Examples:/n/tServerXMLHTTP1.exe 98007/n/t" "ServerXMLHTTP1.exe 98007 1")); printf(_T("/n/nPress Enter to continue...")); getchar(); return -1; } try { HRESULT hr = CoInitialize(NULL); CHECK_HR(hr); // The Method (GET[0]/POST[1]/SOAP[2]) int iCallMethod = 0; if(argc >= 3 && argv[2] != NULL) iCallMethod = atoi(argv[2]); CallWebService((LPCTSTR)argv[1], iCallMethod); } catch(int) { //TODO: Error handling printf(_T("Exception raised!")); } CoUninitialize(); printf(_T("/n/nPress Enter to continue...")); getchar(); return 0;}
Output: