C#下的webservcie 实现代码,很简单一看就清楚了是完成什么样的功能了
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
namespace WebHelloZ5
{
/// <summary>
/// Service1 的摘要说明。
/// </summary>
public class Service1 : System.Web.Services.WebService
{
public Service1()
{
//CODEGEN:该调用是 ASP.NET Web 服务设计器所必需的
InitializeComponent();
}
#region Component Designer generated code
//Web 服务设计器所必需的
private IContainer components = null;
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
// WEB 服务示例
// HelloWorld() 示例服务返回字符串 Hello World
// 若要生成,请取消注释下列行,然后保存并生成项目
// 若要测试此 Web 服务,请按 F5 键
//[WebMethod]
//public string HelloWorld1()
//{
// return "Hello World";
//}
[WebMethod]
public string HelloWorld(int nArg, string strArg)
{
return strArg+ nArg.ToString();
}
}
}
下面就是调用webservice时,网络上大家发送的数据包了
Client请求数据:
POST /WebHelloZ5/Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
<?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>
<HelloWorld xmlns="http://tempuri.org/">
<nArg>int</nArg>
<strArg>string</strArg>
</HelloWorld>
</soap:Body>
</soap:Envelope>
Server回应数据:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>
<HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>string</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>
VC7下的自动生成的代理类,如下所示:
template <typename TClient>
inline HRESULT CService1T<TClient>::HelloWorld(
int nArg,
BSTR strArg,
BSTR* HelloWorldResult
)
{
HRESULT __atlsoap_hr = InitializeSOAP(NULL);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_INITIALIZE_ERROR);
return __atlsoap_hr;
}
CleanupClient();
CComPtr<IStream> __atlsoap_spReadStream;
__CService1_HelloWorld_struct __params;
memset(&__params, 0x00, sizeof(__params));
__params.nArg = nArg;
__params.strArg = strArg;
__atlsoap_hr = SetClientStruct(&__params, 0);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_OUTOFMEMORY);
goto __skip_cleanup;
}
__atlsoap_hr = GenerateResponse(GetWriteStream());
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_GENERATE_ERROR);
goto __skip_cleanup;
}
__atlsoap_hr = SendRequest(_T("SOAPAction: \"http://tempuri.org/HelloWorld"rn"));
if (FAILED(__atlsoap_hr))
{
goto __skip_cleanup;
}
__atlsoap_hr = GetReadStream(&__atlsoap_spReadStream);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_READ_ERROR);
goto __skip_cleanup;
}
// cleanup any in/out-params and out-headers from previous calls
Cleanup();
__atlsoap_hr = BeginParse(__atlsoap_spReadStream);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_PARSE_ERROR);
goto __cleanup;
}
*HelloWorldResult = __params.HelloWorldResult;
goto __skip_cleanup;
__cleanup:
Cleanup();
__skip_cleanup:
ResetClientState(true);
memset(&__params, 0x00, sizeof(__params));
return __atlsoap_hr;
}
流程为:
1 初始化参数列表( SetClientStruct(&__params, 0);)
|
V
2.生成发送数据请求(GenerateResponse(GetWriteStream());SendRequest(_T("SOAPAction: \"http://tempuri.org/HelloWorld"rn"));)
|
V
3.接收和解析回应数据(BeginParse(__atlsoap_spReadStream);)
|
V
4.清理工作
Python代码:
#author:zfive5(zhaozidong)
#email: zfive5@yahoo.com.cn
import httplib
import xml.parsers.expat
import urlparse
class ZFive5Web:
def __init__(self, url,xmlns):
self.url=url
self.xmlns=xmlns
self.ret=""
self.data=""
def gen_request(self,strfunc,strxmlns,dictarg):
ret="<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/">"
ret+="<soap:Body>"
ret+="<%s xmlns=\"%s/\">"%(strfunc,strxmlns)
for (k,v) in dictarg.items():
if k is int:
ret+="<%s>%s</%s>"%(k,str(v),k)
else:
ret+="<%s>%s</%s>"%(k,v,k)
ret+="</%s>"%(strfunc)
ret+="</soap:Body>"
ret+="</soap:Envelope>"
return ret
def hello_world(self,argl):
func="HelloWorld"
addr=urlparse.urlparse(self.url)
argd={}
argd["nArg"]=argl[0]
argd["strArg"]=argl[1]
try:
header={}
header['Host']='localhost'
header['Content-Type']='text/xml'
header['SOAPAction']='\"%s/%s\"'%(self.xmlns,func)
conn=httplib.HTTPConnection(addr[1])
print self.gen_request(func,self.xmlns,argd)
conn.request('POST','/WebHelloZ5/Service1.asmx',self.gen_request(func,self.xmlns,argd),header)
resp=conn.getresponse()
dataxml=resp.read()
def start_element(name, attrs):
pass
def end_element(name):
if name=='HelloWorldResult':
self.ret=self.data
#elif name=='OurPutArg':
# argl[0]=self.temp
def char_data(data):
self.data=data
pxml=xml.parsers.expat.ParserCreate()
pxml.StartElementHandler = start_element
pxml.EndElementHandler = end_element
pxml.CharacterDataHandler = char_data
pxml.Parse(dataxml, 1)
except:
return None
return self.ret
def test():
A=ZFive5Web("http://127.0.0.1/WebHelloZ5/Service1.asmx","http://tempuri.org")
l=[1,'121']
ret=A.hello_world([1,'121'])
if __name__ == '__main__':
assert test()
流程与上差不多如果实现分析.asmx?WDSL文件就完全可以vs中的添加web引用的功能,这里
剩下的主要是特殊符号的处理和类型转化工作。