SOAP及Rest的调用区别参照如下:

REST似乎在一夜间兴起了,这可能引起一些争议,反对者可以说REST是WEB诞生之始甚而是HTTP出现之日就相伴而生的原则。但是毋庸置疑的事实是,在Google和Yahoo等网络巨头发布的相同功能的Web Service API中,REST无疑受到更多的青睐,因此是不是可以这样说:RPC在一夜之间衰落了?

在一篇作业的小文章里讨论整套RPC的原理,无疑太过庞大了,况且RPC在Web Service领域的应用也无过XML-RPC以及由此延伸的SOAP而已。在原理上唯一重要的,是传统程序的函数调用和返回在RPC中被请求和应答代替了而已。既然如此,在讨论REST之前先阐述SOAP,可能是合乎逻辑的顺序。

什么是SOAP?

SOAP (Simple Object Access Protocol) 顾名思义,是一个严格定义的信息交换协议,用于在Web Service中把远程调用和返回封装成机器可读的格式化数据。事实上SOAP数据使用XML数据格式,定义了一整套复杂的标签,以描述调用的远程过程、参数、返回值和出错信息等等。而且随着需要的增长,又不得增加协议以支持安全性,这使SOAP变得异常庞大,背离了简单的初衷。另一方面,各个服务器都可以基于这个协议推出自己的API,即使它们提供的服务及其相似,定义的API也不尽相同,这又导致了WSDL的诞生。WSDL (Web Service Description Language) 也遵循XML格式,用来描述哪个服务器提供什么服务,怎样找到它,以及该服务使用怎样的接口规范,简言之,服务发现。现在,使用Web Service的过程变成,获得该服务的WSDL描述,根据WSDL构造一条格式化的SOAP请求发送给服务器,然后接收一条同样SOAP格式的应答,最后根据先前的WSDL解码数据。绝大多数情况下,请求和应答使用HTTP协议传输,那么发送请求就使用HTTP的POST方法。

什么是REST?

REST (REpresentational State Transfort) 形式上应该表述为客户端通过申请资源来实现状态的转换,在这个角度系统可以看成一台虚拟的状态机。抛开R. T. Fielding博士论文里晦涩的理论不说,REST应该满足这样的特点:)客户端和服务器结构;)连接协议具有无状态性;)能够利用Cache机制增进性能;)层次化的系统;)按需代码。说到底,REST只是一种架构风格,而不是协议或标准。但这种新的风格(也许已经历史悠久?)对现有的以SOAP为代表的Web Service造成的冲击也是革命性的,因为它面向资源,甚至连服务也抽象成资源,因为它和HTTP紧密结合,因为它服务器无状态。

REST与SOAP的区别

因为SOAP并不假定传输数据的下层协议,因此必须设计为能在各种协议上运行。即使绝大多数SOAP是运行在HTTP上,使用URI标识服务,SOAP也仅仅使用POST方法发送请求,用一个唯一的URI标识服务的入口。举一个图书馆在线查询管理系统为例,服务提供者必须为每一本书提供一个内部标识,然后可能定义一个listBooks操作来返回一系列图书,一个getBook操作来返回指定的图书,一个createBook操作来向数据库加入新增的图书,一个deleteBook操作来删除作废的图书,每个操作都有各自的参数,尤其是用内部标识来标识操作的图书。这种设计被诟病之处,在于deleteBook操作也要用POST方法来发送,而其实HTTP协议有更和逻辑的DELETE方法可用。REST正是这样设计的,REST为每一个资源(此处是图书)指定一个唯一的URI,而用HTTP的4种方法GET、POST、PUT、DELETE直观地表示获取、创建、更新和删除图书。同时图书集合也是和单本的图书不同的资源,如果用/books来代表图书列表,/books/ID来代表标识为ID的图书,那么对/books的GET操作就代表返回整个图书列表,对/books/ID的DELETE操作代表删除指定的图书,等等。

REST的优点

REST简单而直观,把HTTP协议利用到了极限,在这种思想指导下,它甚至用HTTP请求的头信息来指明资源的表示形式(如果一个资源有多种形式的话,例如人类友善的页面还是机器可读的数据?),用HTTP的错误机制来返回访问资源的错误。由此带来的直接好处是构建的成本减少了,例如用URI定位每一个资源可以利用通用成熟的技术,而不用再在服务器端开发一套资源访问机制。又如只需简单配置服务器就能规定资源的访问权限,例如通过禁止非GET访问把资源设成只读。

服务器无状态带来了更多额外好处,因为每次请求都包含响应需要的所有信息,所有状态信息都存储在客户端,服务器的内存从庞大的状态信息中解放出来。而且现在即使一台服务器突然死机对客户的影响也微乎其微,因为另一台服务器可以马上代替它的位置,而不需要考虑恢复状态信息。更多的缓存也变成可能,而之前由于服务器有状态,对同一个URI的请求可能导致完全不同的响应。总体结果是,网络的容错性和延展性都增强了,这些本来是WEB设计的初衷,日趋复杂和定制的WEB把它们破坏了,现在REST又返璞归真,试图把Web Service带回简单的原则中来。

REST是万能的吗?

但是REST就是万能的吗?无状态带来了巨大的优势,同时也带来了难以解决的问题,例如,怎样授权特定用户才能使用的服务?怎样验证用户身份?如果坚持服务器无状态,也就是不记录用户登录状态,势必要求每一次服务请求都包含完整的用户身份和验证信息。在这种情况下,怎样避免冒认?怎样避免用户信息泄漏?事实上,构建REST附属的安全机制已经在讨论中,其结果无非导致另一个SOAP:复杂的需求摧残了易用性。

REST的支持者声称REST的请求和应答数据简单可读,而SOAP则需要一系列繁琐的封装;即使如此,SOAP仍然不能达到接口的一致性,不同的厂商有各自的接口,而REST只使用HTTP定义的方法,因此是通用的。事实确实如此吗?试想用REST实现两数求和的服务,如果按照建议的做法,把服务(此处是加法)作为一个资源,参数(此处是两个加数)作为请求的参数,结果以XML或JSON语法返回,是否比SOAP更简单易用?通用接口仍然没法达到,因为资源的名称、参数的名称、结果的格式仍然是服务提供者定义的。为了解决这个问题,提出了WASL(Web Application Description Language)来描述REST接口。WADL就像是WSDL的REST版,随着REST被应用到复杂的领域,SOAP的影子无处不在。

面向资源和面向事务

REST在面向资源的应用中左右逢源,但在面向事务的应用中却未如人意。面向资源的应用操作简单,无非创建、读取、改变、删除几项,但是面向事务的应用不允许用户直接操作资源,用户只需向系统提交一个事务说明要求,然后等待事务的完成,就如一个网上银行的用户不直接修改账户和存款,而是提交一个事务告诉银行自己要转账。如果把这样的服务看成一种资源,通过向资源发送POST请求完成事务,那不过是SOAP的翻版而已,无论是这样,还是通过PUT来创建事务,都改变了系统的状态(资源本身未改变,此处是改变了用户的余额),显然违背了REST直观的初衷。

事实上,一些Web Service提供者提供的REST API只有REST的外壳,传输的请求和应答全然是简化了的SOAP,这种新瓶装旧酒的做法只是加深了标准的分歧而已。归根结底REST无法简单地解决一些应用,因此我们只能看到SOAP在REST外壳下的借尸还魂。没有一项技术能一劳永逸地解决所有问题,只需要在预定的约束下优美地解决所在领域的问题就足够了。一项新技术推出的时候总是引来无数的跟风和吹捧,只有当尘埃落定之后才能得到中肯的评价。

创建服务http://localhost:15383/WebService1.asmx,如下:

/// <summary>
/// WebService1 的摘要说明
/// </summary>
//SOAP1.1调用时的SOAPAction=namespace+methodName
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 比如头部文件Content-Type为"application/json"时,需取消下列注释
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。
// [System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{ [WebMethod]
public string HelloWorld(My my1, My my2)
{
return my1.Name + " " + my1.Value + " " + my2.Name + " " + my2.Value;
} [WebMethod]
public string MyHello(string myname, string name)
{
return myname + name;
}
} public class My
{
public string Name { get; set; } public string Value { get; set; }
}

SOAP1.1 与 SOAP1.2 区别:

SOAP 1.2 uses “application/soap+xml” as Content-Type and SOAP 1.1 uses “text/xml”.
SOAP 1.2 does not use SOAPAction header line.
SOAP 1.2 uses “http://www.w3.org/2003/05/soap-envelope” as the envolope namespace and SOAP 1.1 uses “http://schemas.xmlsoap.org/soap/envelope/”

WebService服务的具体调用均可参照服务提供的说明。

一、使用SOAP1.1调用示例,以HelloWorld为例:

------头部信息--------
POST /WebService1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld" ------Body信息--------
<?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/">
<my1>
<Name>string</Name>
<Value>string</Value>
</my1>
<my2>
<Name>string</Name>
<Value>string</Value>
</my2>
</HelloWorld>
</soap:Body>
</soap:Envelope> ------响应信息--------
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>

二、使用SOAP1.2调用示例,以HelloWorld为例:

--------头部信息---------
POST /WebService1.asmx HTTP/1.1
Host: localhost
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length --------Body信息---------
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<HelloWorld xmlns="http://tempuri.org/">
<my1>
<Name>string</Name>
<Value>string</Value>
</my1>
<my2>
<Name>string</Name>
<Value>string</Value>
</my2>
</HelloWorld>
</soap12:Body>
</soap12:Envelope> --------响应信息---------
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length <?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>string</HelloWorldResult>
</HelloWorldResponse>
</soap12:Body>
</soap12:Envelope>

c#调用示例如下:

string str = "";
str += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
str += "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">";
str += " <soap12:Body> ";
str += " <HelloWorld xmlns=\"http://tempuri.org/\"> ";
str += " <my1> ";
str += " <Name>string</Name> ";
str += " <Value>string</Value> ";
str += " </my1> ";
str += " <my2> ";
str += " <Name>string</Name> ";
str += " <Value>string</Value> ";
str += " </my2> ";
str += " </HelloWorld> ";
str += " </soap12:Body>";
str += "</soap12:Envelope>"; WebRequest request = HttpWebRequest.Create("http://localhost:15383/WebService1.asmx");
byte[] bs = Encoding.UTF8.GetBytes(str);
request.Method = "POST";
request.Timeout = ;
//SOAP1.1调用时需加上头部信息request.Headers.Add("SOAPAction", "http://tempuri.org/HelloWorld");
request.ContentType = "application/soap+xml; charset=UTF-8";
request.ContentLength = bs.Length;
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, , bs.Length);
reqStream.Close();
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
XmlDocument doc = new XmlDocument();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
String retXml = sr.ReadToEnd();
sr.Close();
doc.LoadXml(retXml);
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
//此处是soap1.2,如果是soap1.1就应该如下:mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
mgr.AddNamespace("soap12", "http://www.w3.org/2003/05/soap-envelope");
//解析XML
var xmlNode = doc.SelectSingleNode("//soap12:Body/*", mgr);
Console.WriteLine(xmlNode.FirstChild.InnerText);
} Console.ReadKey();

3.使用HttpPost方式:

简单参数(不是对象),比如MyHello方法,依照如下,也可以使用HttpGet方式:

------请求信息--------
POST /WebService1.asmx/MyHello HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: length myname=string&name=string ------响应信息--------
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length <?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">string</string>

如果是使用复杂对象,上述方式便不能正常工作,可以在WebService上加上[System.Web.Script.Services.ScriptService],使用json的数据传输方式调用,如下:

c# WebService SOAP及Rest调用的更多相关文章

  1. [转]Net 下采用GET/POST/SOAP方式动态调用WebService C#实现

    本文转自:http://www.cnblogs.com/splendidme/archive/2011/10/05/2199501.html 一直以来,我们都为动态调用WebService方法而烦恼. ...

  2. .Net 下采用GET/POST/SOAP方式动态调用WebService的简易灵活方法(C#) [轉]Redfox

    一直以来,我都为动态调用WebService方法而烦恼.在.Net环境下,最常用的方法就是采用代理类来调用WebService,可以通过改变代理类的Url属性来实现动态调用,但当xmlns改变时就会出 ...

  3. CXF发布webService服务以及客户端调用

    这篇随笔内容是CXF发布webService服务以及客户端调用的方法 CXF是什么? 开发工作之前需要下载CXF和安装 下载地址:http://cxf.apache.org 安装过程: <1&g ...

  4. RobotFrameWork webservice soap接口测试 (二)

    上一篇提到做soap接口测试自己简单的写了个py,然后就简单的实现了个客户端能对远程接口进行调用,对返回的数据进行解析,可后面想着也觉得不对劲,soap协议虽说不像http协议那么普及,但是现在很多公 ...

  5. webService(SOAP)性能测试脚本

    本文以天气预报的webService为基础进行学习   webService地址:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx ...

  6. java Webservice(一)HttpClient远程调用

    我们将Web Service发布在Tomcat或者其他应用服务器上后,有很多方法可以调用该Web Service,常用的有两种: 1.通过浏览器HTTP调用,返回规范的XML文件内容      2.通 ...

  7. 浅谈WebService SOAP、Restful、HTTP(post/get)请求

    http://www.itnose.net/detail/6189456.html 浅谈WebService SOAP.Restful.HTTP(post/get)请求 2015-01-09 19:2 ...

  8. WebService学习总结(四)——调用第三方提供的webService服务

    http://www.cnblogs.com/xdp-gacl/p/4260627.html 互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他 ...

  9. loadrunner做webservice接口之简单调用

    今天听大神讲了webservice做接口,我按照他大概讲的意思自己模拟实战了下,可能还有很多不对,一般使用webservice做接口,会使用到soapui,但是用了loadrunner以后发现lr很快 ...

随机推荐

  1. 团队Alpha冲刺(三)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:鸿杰 组员10:刘一好 组员11:何宇恒 展示组内最 ...

  2. 在服务器中使用 Entity Framework 的 Migration 更新数据库

    在开发环境中,每次我们对要对数据库进行更改,比如增加修改表字段等.改好Entity类后,我们只需在Nuget程序包管理控制台运行 update-database 脚本却可: update-databa ...

  3. beta阶段评语

    首先我说一下自己心中的排序 1.俄罗斯方块 2 连连看 3 考试管理系统 4 食物链教学软件 5 约跑App 6 礼物挑选小工具 我的理由: 新峰的俄罗斯的方块,虽然当初的亮点没做出来,但是整体流程完 ...

  4. websocket服务器+客户端

    <?php $demo = new ws('192.168.90.47',12345); $demo->run(); class ws { //当前服务端主连接 private $curr ...

  5. TP中CURD操作

    CURD操作 CURD操作也就是模型操作数据表的基本操作.C(Create).U(Update).R(Read).D(Delete)操作就是增删改查操作. 6.1.增加操作 回想一下在mysql中增加 ...

  6. lxs1314 is not in the sudoers file. This incident will be reported.

    虚拟机下面  普通用户用sudo执行命令时报"xxx is not in the sudoers file.This incident will be reported"错误,解决 ...

  7. 【bzoj5174】[Jsoi2013]哈利波特与死亡圣器 二分+树形dp

    题目描述 给你一棵以1为根的有根树,初始除了1号点为黑色外其余点均为白色.Bob初始在1号点.每次Alice将其中至多k个点染黑,然后Bob移动到任意一个相邻节点,重复这个过程.求最小的k,使得无论B ...

  8. 【Java】时间转json格式化

     @DateTimeFormat(pattern="yyyy-MM-ddHH:mm:ss")     @JsonFormat(pattern="yyyy-MM-ddHH: ...

  9. 【JavaScript】离线应用与客户端存储

    一.前言        这章非常重要,由于之后需要负责平台手机APP的日后维护,如何让用户在离线状态下正常使用,以及联网后的数据合并变得非常重要. 二.内容        离线检测 navigator ...

  10. NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)

    神tm比赛时多清个零就有60了T T 首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP.设f[i][j]表示比最短路多走i的长度,到j的方案数. 我们发现如果在最短路上的和零边会有后向性, ...