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\"\r\n")); 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\"\r\n"));) | V 3.接收和解析回应数据(BeginParse(__atlsoap_spReadStream);) | V 4.清理工作
Python代码:
#author:zfive5(zhaozidong) #email: [email protected]
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引用的功能,这里 剩下的主要是特殊符号的处理和类型转化工作。 
|