一、Web Services简介
Web Services是支持客户端与服务器通过网络互操作的一种软件系统,是一组可以通过网络调用的应用程序API。
Web 服务是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作。Web Service 最基本的组成部分为服务的提供者(Service Provider)和服务的请求者(Service Requester)。Web Service 两端的应用是通过基于标准的 XML 格式的协议进行通信的,这种最常用的协议就是 SOAP(Simple Object Access Protocol)。
1、实现方式
WebService原来有两种方式,一是SOAP协议方式,在这种方式下需要WSDL,UDDI等,二是REST方式,这种方式根本不需要WSDL,UDDI等。
REST是完全不同的思路,它充分利用了HTTP协议的4个主要verb把RPC操作分成4类:
- GET:进行幂等的资源获取操作
- POST:创建资源
- PATCH:修改资源
- DELETE:删除资源
备注:RESTful是个形容词,形容根据这个思路设计出来的REST风格的API
- SOAP:Simple Object Access Protocol 简单对象访问协议(XML,RPC实现)。异步处理与调用,形式化契约,有状态的操作。
- REST:Representational State Transfer 表示性状态转移(HTTP,URL实现)。有限的带宽和资源,完全无状态的操作,缓存考虑。
2、SOAP协议:Simple Object Access Protocol,简单对象访问协议
它是在分散或分布式的环境中交换信息的简单协议,是一种基于XML的协议,需要绑定一个网络传输协议来完成信息的传输,这个协议通常是Http或Https,但也可以使其他协议。
SOAP可以理解为SOAP=HTTP+RPC+XML。
它包括四个部分:
- SOAP封装:它定义了一个框架,描述消息中的内容是描述,是谁发送的,谁又应当接收并处理;
- SOAP编码规则:定义了一种序列化的机制,用于表示应用程序需要使用的数据类型的实例;
- SOAP RPC:表示一种协定,用于表示远程过程调用和应答;
- SOAP绑定:它定义了SOAP使用哪种协议来进行交换信息。使用Http/TCP/UDP都可以。与WCF中的绑定概念一致。
1、SOAP包:soap是一种协议,也是一种用于发送消息的格式,所以可以叫它soap包.
Soap包由封套Envelope(信封)组成,信封由一个soap头和包体组成,其中包体是必须的。
换句话说,SOAP协议只是用来封装消息用的,封装后的消息你可以通过各种已有的协议来传输,如Http、Https、Tcp、UDP、SMTP等,甚至你还可以自定义协议。然而Web Service是采用基于Http协议来传输数据的。
关于使用Https协议来访问Web Services的方法可以参考这个文章:如何利用 SSL 调用 Web 服务。
2、UDDI:统一描述、发现和集成(Universal Description, Discovery, and Integration)
它是一个基于XML的跨平台的描述规范,可以使世界范围内的企业在互联网上发布自己所提供的服务供其他客户查询使用。
3、WSDL:Web服务描述语言(Web Services Description Language),
它是为描述Web服务发布的XML格式。用于描述服务器端口访问方式和使用协议的细节,通常用来辅助生产服务器和客户端代码及配置信息。
二、WebService
1、建立Web服务
在空的Web服务项目中,添加Web服务项: SelftSerivice.asmx。运行一次。
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] public class SelftSerivice : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return "Hello World"; } }
2、在客户调用端:
首先生成代理,在同一解决方案中,添加一个控制台项目,添加一“服务引用”,直接从web服务地址查找服务生成代理。
然后调用:
internal class Program { private static void Main(string[] args) { FirstInstance.SelftSeriviceSoapClient client = new FirstInstance.SelftSeriviceSoapClient(); Console.WriteLine(client.HelloWorld()); } }
3、使用Fiddler工具进行抓包分析
这是客户端请求时的包(http头省略):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <HelloWorld xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ UnicodeTest.FirstInstance" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/> </s:Body> </s:Envelope>
这是服务端响应的包:
<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"> <soap:Body> <HelloWorldResponse xmlns="http://tempuri.org/"> <HelloWorldResult>Hello World</HelloWorldResult> </HelloWorldResponse> </soap:Body> </soap:Envelope>
三、如何对类实例进行传输
[WebMethod] public Customer GetCustomer() { Customer customer = new Customer { Unid = 13, CustomerName = "Songjiang", CreateTime = DateTime.Now, Telephone = new Call { Mobile = "1111111", FirmCall = "2222", HomeCall = "3333" } }; return customer; }
客户端:
public void TestCustomerSoap() { ws.Customer customer = new ws.Customer(); ws.SelfService client = new ws.SelfService(); customer = client.GetCustomer(); Console.WriteLine(customer.CustomerName); }
从WS返回的soap包是:
<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"> <soap:Body> <GetCustomerResponse xmlns="http://tempuri.org/"> <GetCustomerResult> <Unid>13</Unid> <CustomerName>Songjiang</CustomerName> <CreateTime>2010-03-31T11:40:52.3125+08:00</CreateTime> <Telephone> <HomeCall>3333</HomeCall> <Mobile>1111111</Mobile> <FirmCall>2222</FirmCall> </Telephone> </GetCustomerResult> </GetCustomerResponse> </soap:Body> </ soap:Envelope >
四、SoapFormatter
包中实例的的内容与xml数据格式化是很相近的。只是在整个过程中,自己没有进行显式的xml格式化,而由ws进行soap序列化。
Soap序列化器“SoapFormatter”,同XmlSerializer一样,也是把数据保存成xml文件,里面除了保存的内容还有些额外的Soap信息。
XmlSerializer见: https://www.cnblogs.com/springsnow/p/9469399.html
添加名称空间:using System.Runtime.Serialization.Formatters.Soap;
public void TestSoapSerialize() { Customer customer = new Customer { Unid = 13, CustomerName = "Songjiang", CreateTime = DateTime.Now, Telephone = new Call { Mobile = "1111111", FirmCall = "2222", HomeCall = "3333" } }; FileStream fs = new FileStream("xmlSoap.xml", FileMode.Create); SoapFormatter formatter = new SoapFormatter(); formatter.Serialize(fs, customer); fs.Close(); }
内容为一个完整的封套。
<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"> <soap:Body> <GetCustomerResponse xmlns="http://tempuri.org/"> <GetCustomerResult> <Unid>13</Unid> <CustomerName>Songjiang</CustomerName> <CreateTime>2010-03-31T11:40:52.3125+08:00</CreateTime> <Telephone> <HomeCall>3333</HomeCall> <Mobile>1111111</Mobile> <FirmCall>2222</FirmCall> </Telephone> </GetCustomerResult> </GetCustomerResponse> </soap:Body> </ soap:Envelope >
五、客户端配置文件
注意下面客户端终结点的“bindingConfiguration”要引用在bindings节点中的配置的名称。如IScbcWebserviceEntranceServiceSoapBinding。
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="SAPServiceSoap" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" /> <binding name="IScbcWebserviceEntranceServiceSoapBinding" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://10.118.1.2:8010/wsSCBC.asmx" binding="basicHttpBinding" bindingConfiguration="wsSCBCSoap" contract="ServiceReference1.wsSCBCSoap" name="wsSCBCSoap" /> <endpoint address="http://10.126.124.35:8081/ekp/sys/webservice/scbcWebserviceEntrance" binding="basicHttpBinding" bindingConfiguration="IScbcWebserviceEntranceServiceSoapBinding" contract="OAFlow.IScbcWebserviceEntrance" name="IScbcWebserviceEntrancePort" /> </client> </system.serviceModel> </configuration>
客户端代码需要引用终结点配置名。如IScbcWebserviceEntrancePort。
OAFlow.ScbcWebserviceEntranceClient oaFlow = new OAFlow.ScbcWebserviceEntranceClient("IScbcWebserviceEntrancePort"); string ret = oaFlow.execute(o.ToString());
1、修改WebService接收长度:
<binding name="SAPServiceSoap" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />