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
//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。