由于項目需要,需要實作VC調用WebService接口,之前沒接觸過這個,是以花了一天找了點資料,并自己編寫了demo。
1. 首先看了Soap相關資料,見http://www.w3school.com.cn/ws.asp。 調用WebService有幾種方法, 一是直接采用托管方式利用add web Reference,操作非常簡單友善,
但是貌似在VS2008中已無法實作了,是以并沒有做demo。
另外的方法就是非托管的,其中也包括幾種方法,第一種是采用Add web Reference實作,同樣貌似在VS2008裡無法實作,資料:http://www.vckbase.com/index.php/wv/1408.
另外一種非托管的方法就是采用Soap ToolKit3.0 SDK實作,這方面資料也很多,http://www.yesky.com/20020517/1611650.shtml
2. demo編寫, 自己編寫的調用天氣預報的Web Service接口
#include "stdafx.h"
#import <msxml4.dll>
//using namespace MSXML2
#import "C:\Program Files (x86)\Common Files\MSSoap\Binaries\mssoap30.dll" named_guids \
exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", \
"_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")
using namespace MSSOAPLib30;
void Add(LPWSTR cityName)
{
ISoapSerializerPtr Serializer;
ISoapReaderPtr Reader;
ISoapConnectorPtr Connector;
// Connect to the service.
if(FAILED(Connector.CreateInstance(__uuidof(HttpConnector30)))) //建立對象
{
wprintf(_T("failed"));
}
Connector->Property[_T("EndPointURL")] =_T("http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"); //wsdl路徑
Connector->Connect();
// Begin the message. //消息體
Connector->Property[_T("SoapAction")] = _T("http://WebXml.com.cn/getWeather"); //函數體參數
Connector->BeginMessage();
Serializer.CreateInstance(__uuidof(SoapSerializer30));
Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
// Build the SOAP Message.
Serializer->StartEnvelope(_T("Soap"),_T(""),_T(""));
Serializer->StartBody("");
Serializer->StartElement(_T("getWeather"),_T("http://WebXml.com.cn/"),_T(""),_T("Soap")); //函數處理
Serializer->StartElement(_T("theCityCode"),_T(""),_T(""),_T("Soap"));
Serializer->WriteString(cityName); //參數處理
Serializer->EndElement();
Serializer->EndElement();
Serializer->EndBody();
Serializer->EndEnvelope();
Connector->EndMessage();
Reader.CreateInstance(__uuidof(SoapReader30));
wprintf(_T("here"));
Reader->Load(_variant_t((IUnknown*)Connector->OutputStream),""); //加載傳回資料
// Display the result.
MSXML2::IXMLDOMElementPtr pstr = Reader->RpcResult;
char buff[1024] ={0};
strncpy(buff,pstr->text,1024);
printf("Answer:%s\n",buff);
}
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
Add(_T("杭州"));
CoUninitialize();
getchar();
return 0;
}
上述使用還是比較簡單和清晰的,對照着這個http://www.yesky.com/20020517/1611650.shtml資料就行了。一開始我使用
using namespace MSXML2
出現好多錯誤:
e:\vc工程\vcstudy\webservice\webservice\debug\mssoap30.tlh(324) : error C2872: 'IXMLDOMNode' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v6.0a\include\msxml.h(531) : IXMLDOMNode'
1> or 'e:\vc工程\vcstudy\webservice\webservice\debug\msxml4.tlh(2837) : MSXML2::IXMLDOMNode'
最後把該命名空間的語句去掉,用手寫實作
MSXML2::IXMLDOMElementPtr pstr = Reader->RpcResult;
效果:
3. 關于用戶端不需要安裝Soap ToolKit3.0 SDK而能運作程式的方法,見:http://blog.1wanweb.com/post/vc2b2b60-mfc-soapsdke5bc80e58f91websesrvicee68993e58c85.aspx。