c# WebService SOAP及Rest调用

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应该满足这样的特点:1)客户端和服务器结构;2)连接协议具有无状态性;3)能够利用Cache机制增进性能;4)层次化的系统;5)按需代码。说到底,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 = 6000;
//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, 0, 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的数据传输方式调用,如下:

原文地址:https://www.cnblogs.com/lcawen/p/8581250.html

时间: 2024-10-28 18:55:23

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

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

本文转自:http://www.cnblogs.com/splendidme/archive/2011/10/05/2199501.html 一直以来,我们都为动态调用WebService方法而烦恼.在.Net环境下,最常用的方法就是采用代理类来调用WebService,可以通过改变代理类的Url属性来实现动态调用,但当xmlns改变时就会出错,似乎要重新绑定Webservice并重新编译后才能再次运行.我无意中通过百度搜索找了一个采用GET/POST/SOAP方式动态调用WebService的

(转载)Net 下采用GET/POST/SOAP方式动态调用WebService C#实现

转自http://www.cnblogs.com/splendidme/archive/2011/10/05/2199501.html 一直以来,我们都为动态调用WebService方法而烦恼.在.Net环境下,最常用的方法就是采用代理类来调用WebService,可以通过改变代理类的Url属性来实现动态调用,但当xmlns改变时就会出错,似乎要重新绑定Webservice并重新编译后才能再次运行.我无意中通过百度搜索找了一个采用GET/POST/SOAP方式动态调用WebService的简易灵

Webservice soap wsdl的区别

Web Service完结业务诉求:Web Service是真实“就事”的那个,供给一种就事接口的总称.WSDL供给“能办的事的文档阐明”:对要供给的效劳的一种描绘格局.我想帮你的忙,但是我要通知你我都能干啥,以及干这些工作需求的参数类型.SOAP供给“恳求”的规范:向效劳接口传递恳求的格局,包括办法和参数等.你想让人家就事,总得通知人家你想干啥吧,SOAP即是界说这个“恳求”的格局的,按照SOAP界说的“恳求”格局“书写”恳求就能够确保Web Service能够正确的解读你想让它干啥以及你为它

java 实现WebService 以及不同的调用方式

java 实现WebService 以及不同的调用方式 webservice:    就是应用程序之间跨语言的调用    wwww.webxml.com.cn    1.xml    2.    wsdl: webservice description language web服务描述语言        通过xml格式说明调用的地址方法如何调用,可以看错webservice的说明书        3.soap simple object access protoacl (简单对象访问协议)   

?Delphi开发WebService给ASP.NET调用

Delphi开发WebService给ASP.NET调用 说明: 1.本文档分3个部分,分别为: 用Delphi编写WebService 在IIS下部署WebService 在ASP.NET中调用webservice 2.开发环境为Windows XP SP2.Delphi 7.0.IIS 5.1.VS 2008(C#) 一.用Delphi编写WebService 第1步:File → New → Other → WebServices → SOAP Server Application 第2步

Webservice SOAP传输序列化总结(转)

Webservice SOAP传输序列化总结最近在接触Webservice,在使用SOAP协议远程调用本地返回自定义类对象的[WebMethod]方法时总是出错,百度Google后解决问题,现总结如下: 一.所有Webservice中传递的对象都必须能够序列化,这个是作为在网络之间传输的必要条件.XML WebService和SOAP标准支持的数据类型如下: 1.基本数据类型. 标准类型,如:int float bool DateTime string等基本数据类型 2.枚举. 支持枚举Enum

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

WebService学习总结(四)——调用第三方提供的webService服务 互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的Web应用中显示,下面就以获取天气预报数据和查询国内手机号码归属地为例进行说明. 气象中心的管理系统将收集的天气信息并将数据暴露出来(通过WebService Server), 而各大站点的应用就去调用它们得到天气信息并以不同的样式去展示(WebService Client).一. 调用

loadrunner做webservice接口之简单调用

今天听大神讲了webservice做接口,我按照他大概讲的意思自己模拟实战了下,可能还有很多不对,一般使用webservice做接口,会使用到soapui,但是用了loadrunner以后发现lr很快捷和简单,如下: 准备webservice测试接口,我用的是天气预报的接口,地址:http://ws.webxml.com.cn/  天气预报接口地址:http://ws.webxml.com.cn/webservices/DomesticAirline.asmx?wsdl,地址可以打开就能看到他的

Android调用WebService系列之请求调用

好久没写博客,快有3年了.当初想在CTO把自己的技术文章一直延续,可却没有坚持! 开发Android网络App,通讯方式决定了你App所需的能力! 最近正在用Web Service进行通讯,那么就让我来讲讲Web Service吧! 一.了解Web Service是什么? 请查看(http://baike.baidu.com/link?url=7IdTbG7yw6FKJ_CU0NJYny74IsDrgay861ywsm0u_aBBG5zSwkvYgxVopH2iPdyr4_witJRYf_W6W