SOAP的概念应该不是什么新鲜事物了。简单的说,SOAP是以把数据以XML的方式组合起来,然后通过HTTP协议(也可以是其它协议,但是通常总是用http协议)和远程服务进行通信的一个标准,也可以把它认为是一个中间件,起着沟通桥梁的作用。因为当所有的服务都使用同一种标准,那么沟通就比较容易了。
当然不得不承认,SOAP格式的报文内容冗余,并且依赖于定义好的XML schemas,对于手工创建SOAP报文十分复杂,需要借助一些工具来简化工作。因此越来越多的Web服务倾向于使用Restful风格的WebService。
根据SOAP的协议,只需要发送有效的SOAP消息到服务端,就能实现通信。那么如何生成有效的SOAP消息?SOAP官方文档详细说明了SOAP的格式,但官方文档很长,一般人没耐心去读完,大多时候仅仅在需要的时候去查一下,也可以去http://w3school.com.cn/soap/soap_syntax.asp学习一下简化版的。这里介绍一个工具,SoapUI,可以去它官网http://www.soapui.org/下载,它可以通过WSDL生成请求的SOAP消息格式。
ASP.NET中,采用向导创建的Web服务,是SOAP风格的。假设我们创建一个web服务。使用向导,完成如下的代码:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 
usingSystem; 
 usingSystem.Collections.Generic; 
 usingSystem.Linq; 
 usingSystem.Web; 
 usingSystem.Web.Services; 
 namespaceWebService1 
 { 
     /// <summary> 
     /// Summary description for WebService1 
     /// </summary> 
     [WebService(Namespace = "http://tempuri.org/")] 
     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
     [System.ComponentModel.ToolboxItem(false)] 
     
     
     publicclassWebService1 : System.Web.Services.WebService 
     { 
         [WebMethod] 
         publicstringHelloWorld() 
         { 
             return"Hello World"; 
         } 
         [WebMethod] 
         publicintAdd(inta, intb) 
         { 
             returna + b; 
         } 
         /// <summary> 
         /// 把公制单位的汽车转化成以英制单位表示的汽车 
         /// </summary> 
         /// <param name="s"></param> 
         /// <returns></returns> 
         [WebMethod] 
         publiccar ChangeCarUnit(car s) 
         { 
             s.length = s.length * 3.3m; 
             s.width = s.width * 3.3m; 
             s.weight = s.width * 2.2m; 
             returns; 
         } 
     } 
     publicclasscar 
     { 
         publicstringmodel = ""; 
         publicdecimallength = 0; 
         publicdecimalwidth = 0; 
         publicdecimalweight = 0; 
     } 
 }
 | 
  
方法都写在WebService1.asmx文件中,通过web服务的WSDL,可以得到它的SOAP消息格式。这两采用SoapUI输入指定的WSDL文件,即可以自动生成SOAP消息格式。
![clipboard[26] clipboard[26]](http://img1.51cto.com/attachment/201402/7/2359144_1391750081K061.png)
注意:在ASP.net中,可以通过访问WebService1.asmx并且输入查询字符串?WSDL,即在IE浏览器中输入WebService1.asmx?wsdl就可以获得WSDL文件。
还有一点要注意的是,微软生成的WSDL文件,有2个binding,分别表示soap1.1和soap1.2,它都支持。

因此在SoapUI中可以看到2个不同的WebService接口,其实是大同小异的。

双击Add的Request,就可以得到SOAP消息格式了,其中的问号可以输入指定的值,然后点击执行按钮,就又可以得到响应的SOAP消息格式了。
通过SoapUI生成SOAP消息后,就可以自己构造SOAP消息来调用SOAP风格的WebService,因此,只要解决如何生成请求的SOAP消息,我们甚至可以自己实现一个Web服务调用框架,无论是基于PHP,ASP.net,还是javascript。
-----------------------------------------------------------------------
下面的演示如何在javascript中发送SOAP。
一下代码调用之前WebService1中的方法ChangeCarUnit,这个方法把汽车参数从公制为单位的转换成英制单位。
首先手动通过SoapUI获取SOAP消息格式。生成并补充数据,得到如下的格式
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 
<soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:tem="http://tempuri.org/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
       <tem:ChangeCarUnit> 
          
          <tem:s> 
             
             <tem:model>Passat</tem:model> 
             <tem:length>4.87</tem:length> 
             <tem:width>1.834</tem:width> 
             <tem:weight>1435</tem:weight> 
          </tem:s> 
       </tem:ChangeCarUnit> 
    </soapenv:Body> 
 </soapenv:Envelope>
 | 
  
因此只需将这串xml发送到webservice既可。
通过jquery ajax实现。
代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 
<script type="text/javascript"> 
     $(function() { 
         $("#btnclick").click(function() { 
             varsoapmessage = ""; 
             soapmessage += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">'; 
             soapmessage += '<soapenv:Header/>'; 
             soapmessage += '<soapenv:Body>'; 
             soapmessage += '<tem:ChangeCarUnit>'; 
             soapmessage += ' <!--Optional:-->'; 
             soapmessage += ' <tem:s>'; 
             soapmessage += ' <!--Optional:-->'; 
             soapmessage += ' <tem:model>Passat</tem:model>'; 
             soapmessage += ' <tem:length>4.87</tem:length>'; 
             soapmessage += ' <tem:width>1.834</tem:width>'; 
             soapmessage += ' <tem:weight>1435</tem:weight>'; 
             soapmessage += ' </tem:s>'; 
             soapmessage += '</tem:ChangeCarUnit>'; 
             soapmessage += ' </soapenv:Body>'; 
             soapmessage += '</soapenv:Envelope>'; 
             varoption = { 
                 url: 'http://localhost:28689/WebService1.asmx', 
                 type: 'POST', 
                 contentType: 'text/xml', 
                 success: function(result) { 
                     alert(result.documentElement.textContent); 
                 }, 
                 data: soapmessage 
             }; 
             $.ajax(option); 
         }); 
     }); 
 </script> 
 <input value='click'type="button"id="btnclick"/>
 | 
  
点击按钮后,就会将soap消息post到web服务器,并且得到返回消息,返回消息也是基于XML的文本。
通过上面的实例,我们可以通过编写专用的工具来生成SOAP消息,通过封装后,再通过POST方式(比如c#中的HttpWebRequest)来实现webserverice的调用。