【转】WCF光芒下的Web Service

WCF光芒下的Web
Service


学习.NET的开发人员,在WCF的光芒照耀下,Web
Service 似乎快要被人遗忘了。因为身边做技术的人一开口就是WCF多么的牛逼!废话不多,本人很久不写博客,今天总结一下最近几日遇到的几个关于WebService 跨语言的调用问题。

WebService 简介

Web Service也叫XML Web Service
WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

Web
Service的简介就说这么多,大家都懂的,网上的资料太多了,搞过Web
Service编程的人员都知道它的优点,没有搞过WS编程的人员也知道它的优点,这里不再累述。

参考文章: http://baike.baidu.com/view/837392.htm

SOAP 消息结构

要学习WebService 肯定要了解Soap协议,它是WebService的基础。

SOAP(Simple Object Access
Protocol)简单对象访问协议,它是基于XML的消息传递协议,可以让软件组件和基于服务的应用程序能够使用标准的HTTP协议进行通信(SOAP是基于HTTP之上的)。

SOAP的消息文档是一个XML格式的。相信大家都看到过:

SOAP主要是由4部分组成:

SOAP Envelope 

这是XML的顶层元素,语法如下:

(1)元素名为Envelope,必须存在,且为根元素。

(2)该元素可以包含命名空间和生命额外的属性。如果出现额外属性,则必须使用命名空间修饰。

(3)该元素可以包含额外的子元素,如果使用这些子元素,必须有命名空间修饰并且必须跟在SOAP
Body元素之后,也就是说Envelope的直接子元素Header和Body必须排列在最前面。

SOAP Header

Header应该是Envelope中的第一个子元素,为可选的,语法规则如下:

(1)元素名为Header,不是必须存在,但如果存在则必须是SOAP
Envelope的第一个直接子元素。

(2)Header的所有直接子元素都是它的Item,每个Itemdoiu必须有命名空间修饰。

(3)Header的Item也可以包含下级子元素,但这些子元素不是Header的Item,而是具体Item的内容。

此外,SOAP
encodingStyle属性用于指定Header条目的编码风格,mustUnderstand属性和actor属性用于指定如何处理Item和由谁来处理。如:

<ENV:Header>

<uniB2B:Priority
MXLns:uniB2B="some-URI"

ENV:mustUnderstand="1">7</uniB2B:Priority>

</ENV:Header>

SOAP Body

SOAP Body元素提供一个简单的用于消息的最终接收者交换信息的机制。其语法如下:

(1)元素名为Body,必须在SOAP消息中出现,同时必须是SOAP
Envelope的直接子元素,若没有Header,则Body必须是第一个直接子元素;若有Header,则Body必须紧跟Header元素存在。

(2)与Header类似,每个Body的Item都必须由命名空间修饰。此外,Body中有个SOAP
Fault元素,用于指示调用错误信息。

(3)Body的Item下的子元素不是Body的Item了,而是Item的内容

SOAP Fault

用于在SOAP消息中传输错误及状态信息。如果存在则必须是Body的一个Item,且Body中只能出现一次Fault。SOAP
Fault元素有以下几个子元素:

(1) faultcode 必须在SOAP Fault元素中出现

(2)faultstring 该元素是为那些错误代码提供用户可以读懂的错误解释,它不是为程序处理而设置的。

(3)faultactor 该元素描述在消息路径中错误的引发者,它类似于SOAP
actor属性,不过它不是指示Header条目的接收者,而是指示错误源。

(4)tail 该元素用于传输Body元素相关的应用程序的错误消息

3  WebService
5
种模式

请求响应模式

fire-and-forget模式

高级消息模式

增量解析和处理模式

缓存模式

4
 
WebService 自定义SoapHeader安全验证

SOAP 标头提供了一种方法,用于将数据传递到 XML Web
services 方法或从 XML Web
services 方法传递数据,条件是该数据不直接与 XML Web
services 方法的主功能相关。例如,一个 XML Web
services 可能包含若干个 XML Web
services 方法,而每个方法都需要自定义的身份验证方案。您不用将参数添加到每个需要自定义身份验证方案的 XML
Web
services 方法,而可以将引用从 SoapHeader 派生的类的 SoapHeaderAttribute 应用于每个 XML
Web
services 方法。从 SoapHeader 派生的类的实现处理该自定义身份验证方案。按照此方式,XML
Web
services 方法使用 SOAP 标头来仅实现特定于它的功能并添加其他功能。

下面的列表概述接收和处理 SOAP 标头的基本步骤:

创建一个从 SoapHeader 派生的类,表示传入 SOAP 标头的数据。

将一个成员添加到实现 XML Web services 的类或 XML
Web services 客户端代理类(它们属于在第一步创建的类型)。

指定第二步中在 MemberName 属性中创建的成员,将 SoapHeaderAttribute 应用于 XML
Web services 方法或代理类中的对应方法。

在 XML Web
services 方法或 XML Web
services 客户端代码中访问 MemberName 属性,以处理在 SOAP 标头中发送的数据。

验证例子代码:

(1)首先定义一个自定义SoapHeader

public class MyHeader:SoapHeader
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public string PassWord { get; set; }

}

(2) 在WebService暴露的方法中添加SoapHeader描述

[WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class Info : System.Web.Services.WebService
    {
        public SoapUnknownHeader[] unknownHeaders;

        public MyHeader MyHeader { get; set; }

        [WebMethod]
        [SoapHeader("unknownHeaders")]
        public string HelloWorld()
        {
            Console.WriteLine("?>>>>>>>>>>>>>>>>>>>>");
            return "Hello World";
        }

        [SoapHeader("MyHeader", Direction = SoapHeaderDirection.InOut)]
        [WebMethod]
        public string Audit()
        {
            Validate();

            return "这里是验证";
        }

        //验证函数 自定义
        private string Validate()
        {
            if (MyHeader != null)
            {
                if (MyHeader.Name == MyHeader.PassWord)
                {
                    return "验证通过";
                }
                else
                {
                    return "验证失败";
                }
            }
            return "未传递消息头";
        }

}

这里重点看的是服务暴露出来的方法public string Audit()

在WebService中的类定义一个属性  public MyHeader MyHeader { get; set; }
就是我们自定义的SOAPHeader,同时还要在Audit()方法上加上如下描述:

[SoapHeader("MyHeader", Direction = SoapHeaderDirection.InOut)]

如果客户端传递了相应的SoapHeader就会使用此属性来接收消息,主要特性描述中的参数要指向定义的属性名。

(3)客户端生存代理

客户端生成代理大家都知道,工程--右键--添加Web引用即可,现在我们看看里面生成的代码

MyHeader客户端生成的代理类

代理类中生存对应的属性,同时此类也是继承了SoapHeader类。

[System.Web.Services.Protocols.SoapHeaderAttribute("MyHeaderValue", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Audit", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string Audit() {
            object[] results = this.Invoke("Audit", new object[0]);
            return ((string)(results[0]));

}

public MyHeader MyHeaderValue {

get {

return
this.myHeaderValueField;

}

set {

this.myHeaderValueField = value;

}

}

(4)客户端调用

MyService.Info info = new MyService.Info();
MyService.MyHeader myHeader = new MyService.MyHeader();
myHeader.ID = 1;
myHeader.Name = "qingyuan";
myHeader.PassWord = "qingyuan";
info.MyHeaderValue = myHeader;
string content=  info.Audit();

Response.Write(content);

5  异语言之间的调用 

在我们的工作中,很多时候遇到这样的问题,有人说Java不能调用.NET 写WebService。对他们没有撒谎,那WebService跨平台岂不是笑话,其实不是这样的,这个时候我们真正应该研究的是SOAP的自己个组成部分,我们可以使用WSDL来查看他们的不同之处。

.NET生存的WSDL一部分

Java生存的WSDL一部分

这里是同一个SoapHeader生成的WSDL,仔细看看还是有区别的,在java中的缺少一个form元素。 缺少这个元素就导致.NET的序列化机制无法识别这个xml文件。那该怎么办呢。

在.NET的自定义SoapHeader的属性上添加如下描述

[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]

6
 
.NET中获取匿名SoapHeader 内容

很多时候,我们做事情就和孔雀开屏,当然这不是讽刺啊,题外话!我们喜欢强加一些自己的意愿和想法在里面。

我存在一个WebService的服务端,现在客户端调用这个WebService的时候强制提交了一个SOAPHeader报文,希望WebService能够处理。上面一部分我们可以发现客户端提交一个SOAPHeader的时候服务端有一个承载体,因为我们在服务端的时候就在暴露的方法中用SOAPHeader描述过了,现在就是服务端没有使用自定义SOAPHeader描述,而客户端强制提交了一个SOAPHeader,这样我们怎么处理。

1. 客户端定义一个SOAPHeader自定义对象

public class MyInfo:SoapHeader
{
        public MyInfo()
        { 
        }

        public int ID { get; set; }

        public string Name { get; set; }

}

这里是在客户端添加的SoapHeader ,不要在服务端添加此类

2. 客户端代理方法添加SOAPHeader的描述

/*******************************************************************/
        public MyInfo MyInfo { get; set; }

        [SoapHeader("MyInfo", Direction = SoapHeaderDirection.InOut)]
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public string HelloWorld() {
            object[] results = this.Invoke("HelloWorld", new object[0]);
            return ((string)(results[0]));
        }

/*******************************************************************/

这里和普通的代理方式一样,添加客户端SOAPHeader的描述

3.  服务端添加匿名SOAPHeader的处理

public SoapUnknownHeader[] unknownHeaders;

[WebMethod]
        [SoapHeader("unknownHeaders")]
        public string HelloWorld()
        {
            Console.WriteLine("?>>>>>>>>>>>>>>>>>>>>");
            return "Hello World";
        }

服务端需要使用SoapUnknownHeader来接收匿名提交的SoapHeader。因为在服务端没有对应的载体,而在暴露的方法上面也需要添加相应的描述

4.
  客户端调用

MyService.Info info = new MyService.Info();
            MyInfo myInfo = new MyInfo();
            myInfo.ID = 1;
            myInfo.Name = "dddd";
            info.MyInfo = myInfo;
            string name = info.HelloWorld();

Response.Write(name);

启动服务端的调试模式跟踪一下看看提交的数据

 从上图可以看出,数据已经传输过来了,得到的是一个xml格式的数据,对于xml的解析在.NET中不是难事,在此就可以完成匿名SoapHeader报文的发送和接收

7 JavaScript 异步调用WebService 

参考:http://www.cnblogs.com/qingyuan/archive/2009/12/09/1620405.html

http://www.cnblogs.com/jeffreyzhao/archive/2007/07/23/something_about_calling_web_service_method.html

【转】WCF光芒下的Web Service

时间: 2024-08-13 22:09:18

【转】WCF光芒下的Web Service的相关文章

转载——Java与WCF交互(二):WCF客户端调用Java Web Service

在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttpBinding可行,而NetTcpBinding不可行,具体原因待查.昨晚回去重新测试WCF客户端调用Java Web Service,并将过程公布如下: 其实本不需要做web service,只是原来公开的经典的Web service像(http://soapinterop.java.sun.com/rou

Web Service和WCF的到底有什么区别

[1]Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XML扩展标记语言来表示数据(这个是夸语言和平台的关键).微软的Web服务实现称为ASP.NET Web Service.它使用Soap简单对象访问协议来实现分布式环境里应用程序之间的数据交互.WSDL来实现服务接口相关的描述.此外Web services 可以注册到UDDI中心.供其客户查找使用.  

面试题:Web Service与wcf的区别

Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XML扩展标记语言来表示数据(这个是夸语言和平台的关键).微软的Web服务实现称为ASP.NET Web Service.它使用Soap简单对象访问协议来实现分布式环境里应用程序之间的数据交互.WSDL来实现服务接口相关的描述.此外Web services 可以注册到UDDI中心.供其客户查找使用.     

Web Service和WCF的区别。其实二者不属于一个范畴!!!

Web Service和WCF的区别 [1]Web Service:严格来说是行业标准,也就是Web Service 规范. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XML扩展标记语言来表示数据(这个是跨语言和平台的关键).微软的Web服务实现称为ASP.NET Web Service.它使用Soap简单对象访问协议来实现分布式环境里应用程序之间的数据交互.WSDL来实现服务接口相关的描述.此外Web services 可以注册到UDDI中心.供其客户查找使用.     

什么情况下应该使用Web Service?

现在我将列举三种情况,在这三种情况下,你将会发现使用Web service会带来极大的好处.此后,我还会举出不应该使用Web service的一些情况. 跨越防火墙的通信 如果你的应用程序有成千上万的用户,而且他们都分布在世界各地,那么客户端和服务器之间的通信将是一个棘手的问题.那是因为客户端和服务器之间通常都会 有防火墙或者代理服务器.在这种情况下,你想使用DCOM就不是那么简单了,而且,通常你也不愿意把你的客户端程序发布到如此庞大数量的每一个用户手中. 于是,你最终选择了用浏览器作为客户端,

web service &amp;&amp; WCF 学习总结

Web Service和WCF技术都提供了应用程序与应用程序之间的通信.它们都是基于soap消息在客户端和服务端之间进行通信,由于soap消息是一种xml格式,因此传输的数据格式为XML.每次客户端向服务端请求数据时,客户端的服务代理,都会将请求消息转化为soap消息进行传输,而服务端在返回数据时也会将数据转化成soap消息传输.两者提供的服务都可以用WSDL(web service description language)来描述.对于客户端,它们都可以以添加引用的方式来生成服务的代理类,即向

Web Service和WCF的区别

*Web Service和WCF的区别: Web Service是一种行业标准,也就是Web Service规范,既不是框架也不是技术 WCF是一个分布式应用的开发框架,属于特定的技术,或者是平台,既不是标准也不是规范->DCOM协议 分布式组件对象模型 是一系列微软的概念和程序接口,利用这个接口,客户端程序对象能够请求来自网络中另一台计算机上的服务器程序对象. DCOM基于组件对象模型(COM),COM提供了一套允许同一台计算机上的客户端和服务器之间进行通信的接口

Web Service学习笔记

Web Service概述 Web Service的定义 W3C组织对其的定义例如以下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来运行远程系统的请求服务. 这里我们从一个程序猿的视角来观察web service.在传统的程序编码中,存在这各种的函数方法调用.通常,我们知道一个程序模块M中的方法A,向其发出调用请求,并传入A方法须要的參数P,方法A运行完毕后,返回处理结果R.这样的函数或方法调用

JAVA开发Web Service几种框架介绍

在讲Web Service开发服务时,需要介绍一个目前开发Web Service的几个框架,分别为Axis,axis2,Xfire,CXF以及JWS(也就是前面所述的JAX-WS,这是Java6发布所提供的对Web Service服务的一种实现.)前面几项都为开源项目,而其中又以axis2与cxf所最为常用,Axis与XFire已随着技术不断的更替慢慢落幕,而目前也只有axis2和cxf官方有更新,Axis与XFire都已不再更新. 下面就分别介绍下这几个框架之间的区别,以便大家进行更好的选择: