原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]

[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy、WS-Transfer和WSDL,因为WCF元数据结构体系完全是基于WS-MEX等相关的规范之上。熟悉这些基本的WS规范,对于我们全面、深刻的理解WCF整个元数据架构体系具有十分重要的意义。不仅仅是针对元数据,对于后续章节陆续要介绍的内容,比如事务、可靠会话、安全等,我强烈建议读者在正式进行相关部分的学习之前,先对相关的WS规范作一个大致的了解。

通过对WS-MEX的介绍,我们知道:不论是采用WS-Transfer Get操作还是Get Metadata操作,获取到的元数据被封装到回复消息主体部分的<Metadata>结点中,而<Metadata>是一组<MetadataSection>元素的集合。在托管的世界里,<MetadataSection>元素和<MetadataSection>元素集合有相应的类型来表示,那就是我们接下来要着重介绍的MetadataSectionMetadataSet

一、MetadataSection

MetadataSection定义在System.ServiceModel.Description命名空间下,用于用于定义基于某种方言(Dialect)的元数据,该类型和WS-MEX中包含元数据SOAP消息主体的<MetadataSection>结点相匹配。我们不妨现在看看MetadataSection的定义:

   1: [XmlRoot(ElementName="MetadataSection", Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

   2: public class MetadataSection

   3: {    

   4:     //其他成员

   5:     public MetadataSection();

   6:     public MetadataSection(string dialect, string identifier, object metadata);   

   7:    

   8:     [XmlAnyAttribute]

   9:     public Collection<XmlAttribute> Attributes { get; }

  10:     [XmlAttribute]

  11:     public string Dialect { get; set; }

  12:     [XmlAttribute]

  13:     public string Identifier { get; set; }

  14:     [XmlElement("Location", typeof(MetadataLocation), Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

  15:     [XmlElement("MetadataReference", typeof(MetadataReference), Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

  16:     [XmlElement("Metadata", typeof(MetadataSet), Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

  17:     [XmlElement("schema", typeof(XmlSchema), Namespace = "http://www.w3.org/2001/XMLSchema")]

  18:     [XmlElement("definitions", typeof(ServiceDescription), Namespace = "http://schemas.xmlsoap.org/wsdl/")]

  19:     [XmlAnyElement]

  20:     public object Metadata { get; set; }   

  21:  

  22:     //四种预定义元数据方言(Dialect)

  23:     //MEX:http://schemas.xmlsoap.org/ws/2004/09/mex

  24:     public static string MetadataExchangeDialect { get; }

  25:     //WS-Policy:http://schemas.xmlsoap.org/ws/2004/09/policy

  26:     public static string PolicyDialect { get; }

  27:     //WSDL:http://schemas.xmlsoap.org/wsdl/

  28:     public static string ServiceDescriptionDialect { get; }

  29:     //XML Schema:http://www.w3.org/2001/XMLSchema

  30:     public static string XmlSchemaDialect { get; } 

  31: }

但看MetadataSection的定义,你可能觉得没有太多值得关注的地方,如果结合WS-MEX规范,既有很多值得玩味的地方了:

首先,在类型上应用了一个XmlRootAttribute特性,并定义的名称和命名空间分别为:MetadataSection和http://schemas.xmlsoap.org/ws/2004/09/mex。这和WS-MEX 1.1完全吻合。

其次,属性Dialect表述元数据方言,你可以定义任意字符串作为其属性值。在WS-MEX定义了五种预定义元数据方言:MEX、XML Schema、WSDL、WS-Policy和WS-Policy Attachment。除了WS-Policy Attachement,MetadataSection为前面四种定义了静态只读属性,以便方面编程使用。

然后,属性Identifier表示元数据的标识符,这是一个以URI形式表示的字符串,由于受篇幅所限,在上面对WS-MEX的介绍中并没有提及,有兴趣的读者可以参考WS-MEX官方文档的第4部分。Identifier和Dialect最终被序列化后生成<MetadataSection>元素相应的属性(Attribute)。此外,MetadataSection还定义了类型为Collection<XmlAttribute>的Attributes属性,你可以自定义任意的XML属性,最终将会作为<MetadataSection>元素的属性。

而元数据的内容通过包含在属性Metadata中,当整个MetadataSection被序列化后,该属性的值将会被序列化成一个XML元素,其元素的名称和命名空间根据具体的类型决定。从应用在该属性上的一系列XmlElementAttribute特性我们可以看出:MetadataSection为以下几种特殊的类型定义了相应的名称和命名空间:

MetadataLocation

MetadataLocation表示以RUI形式表示的元数据文档的地址,WS-MEX 1.1规定了可以采用元数据文档地址的URI来替代相应元数据的内容。MetadataLocation定义在System.ServiceModel.Description命名空间下,定义如下:

   1: [XmlRoot(ElementName="Location", Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

   2: public class MetadataLocation

   3: {

   4:     public MetadataLocation();

   5:     public MetadataLocation(string location);

   6:  

   7:     [XmlText]

   8:     public string Location { get; set; }

   9: }

MetadataReference

按照WS-Addressing 2004或者WS-Addressing 1.0规范,如果元数据成为一种可被寻址的资源(Addressable Resource),那么可以通过终结点引用(Endpoint Reference)的方式来定位该资源。WS-MEX 1.1规定了可以采用元数据终结点引用来替代相应元数据的内容。元数据终结点引用可以通过MetadataReference来表示,MetadataReference定义于System.ServiceModel.Description命名空间下,定义如下:

   1: [XmlRoot(ElementName = "MetadataReference", Namespace = "http://schemas.xmlsoap.org/ws/2004/09/mex")]

   2: public class MetadataReference : IXmlSerializable

   3: {

   4:    

   5:     public MetadataReference();

   6:     public MetadataReference(EndpointAddress address, AddressingVersion addressVersion);  

   7:     public EndpointAddress Address { get; set; }

   8:     public AddressingVersion AddressVersion { get; set; }

   9: }

MetadataSet

MetadataSet就是我们即将要介绍的用于表示MetadataSection集合,将MetadataSet作为MetadataSection的元数据,意味元数据可以以一种嵌套的形式来表示。

XmlSchema

如果元数据的类型为XmlSchema,即表示以XML Schema方言(Dialect)表示的元数据。

ServiceDescription

关于这里的ServiceDescription,读者千万要注意:这里指的是System.Web.Services.Description.ServiceDescription,而不是System.ServiceModel.Description.ServiceDescription。后者是我们熟悉的对WCF服务的描述(对此不熟悉的读者,可以参考《WCF技术剖析(卷1)》的第7章),前者实际上是对一个WSDL文档的描述。由于WSDL的结构相对复杂,ServiceDescription的定义也不太简单,篇幅所限,本书不会对此作详细的介绍,有兴趣的读者可以参考MSDN类库。如果元数据的类型为ServiceDescription,即表示以WSDL方言(Dialect)表示的元数据。

最后,MetadataSection还定义了如下三个静态方法帮助你快速创建基于WS-Policy策略、XML Schema和WSDL元数据方言的MetadataSection对象:

   1: [XmlRoot(ElementName="MetadataSection", Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

   2: public class MetadataSection

   3: {

   4:    //其他成员

   5:     public static MetadataSection CreateFromPolicy(XmlElement policy, string identifier);

   6:     public static MetadataSection CreateFromSchema(XmlSchema schema);

   7:     public static MetadataSection CreateFromServiceDescription(ServiceDescription serviceDescription);

   8: }

二、 MetdataSet

MetadataSet是WS-MEX 1.1中置于SOAP消息主体部分整个元数据的描述,即对置于SOAP主体部分的<Metadata>所有内容的体现。既然<Metadata>结点是一组<MetadataSection>元素的集合,MetadataSet相应地也就是一组MetadataSection对象的集合,这可以从MetadataSet的定义看出来:

   1: [XmlRoot("Metadata", Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

   2: public class MetadataSet : IXmlSerializable

   3: {

   4:     //其他成员

   5:     public MetadataSet();

   6:     public MetadataSet(IEnumerable<MetadataSection> sections);

   7:  

   8:     [XmlAnyAttribute]

   9:     public Collection<XmlAttribute> Attributes { get; }

  10:     [XmlElement("MetadataSection", Namespace="http://schemas.xmlsoap.org/ws/2004/09/mex")]

  11: public Collection<MetadataSection> MetadataSections { get; }

  12:  

  13:     XmlSchema IXmlSerializable.GetSchema();

  14:     void IXmlSerializable.ReadXml(XmlReader reader);

  15:     void IXmlSerializable.WriteXml(XmlWriter writer);

  16: }

三、WCF元数据架构模型

WCF通过终结点的形式将某个服务暴露出来,而元数据的目的在于帮助服务的消费者如何有效地与该终结点进行交互,以实现对该服务的正常调用。元数据帮助像SvcUtil.exe这样的代码生成工具能够有效地生成客户端代码和配置。WCF在内部构建了一个完善的元数据架构体系,很好地实现了元数据的导出、发布、获取和导入,这个框架体系对元数据的处理大体如图1所示。

 图1 WCF元数据架构体系

图1可以看出,整个元数据框架体系大体分成服务端体系和客户端体系,服务端复杂元数据的导出和发布,客户端实现元数据的获取与导入。元数据的导出、发布、获取和导入这4个基本操作在整个框架体系中的分别实现以下的功能:

在后续的文章中,的我们将针对上述的四个元数据基本操作,对WCF的元数据框架的实现原理进行深入地剖析。

作者:Artech
出处:http://artech.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]的更多相关文章

  1. WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]

    原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-ME ...

  2. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇] 通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding ...

  3. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...

  4. WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]

    原文:WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载] 我们有两种典型的WCF调用方式:通过SvcUtil.exe(或者添加Web引用)导入发布的服务元数据生成服务代理相关的代码 ...

  5. WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?

    原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...

  6. WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]

    原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...

  7. WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?

    原文:WCF技术剖析之二十: 服务在WCF体系中是如何被描述的? 任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过 ...

  8. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇]

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇] 对于WCF服务端元数据架构体系来说,通过MetadataExporter将服务的终结点导出成MetadataSet(参考< ...

  9. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...

随机推荐

  1. Java代码优化策略

    1.生成对象时,合理分配空间和大小:new ArrayList(100); 2.优化for循环: Vector vect = new Vector(1000); For(int i=0; i<v ...

  2. BZOJ 1823: [JSOI2010]满汉全席( 2-sat )

    2-sat...假如一个评委喜好的2样中..其中一样没做, 那另一样就一定要做, 这样去建图..然后跑tarjan. 时间复杂度O((n+m)*K) ------------------------- ...

  3. js基础之冒号

    js中冒号的作用有两种, 转自:http://www.kqiqi.com/knowledge/web-based/506.html 一.?: 操作符 a = expression ? b : c;如果 ...

  4. openrisc 之 Wishbone总线学习笔记——总线互联

    一,总线命名规范 1,wishbone总线接口信号都是高电平有限 2,wishbone接口信号都是以 _i ,或者是 _o 结束.i表示输入, o表示输出. ()表示该信号为总线信号,总线位宽可以大于 ...

  5. ioctl函数详细说明

    本函数影响由fd 参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void *arg */ ) ...

  6. 自定义类StyleSheet跨浏览器操作样式表中的规则

    这是群里网友地瓜提供的一个类,不熟悉样式表对象和样式规则对象的浏览器差异的可以看看 /** * Stylesheet.js: utility methods for scripting CSS sty ...

  7. js获取控件位置

    //获取坐标位置 function getpos(e) { var t=e.offsetTop; var l=e.offsetLeft; var height=e.offsetHeight; whil ...

  8. html里面自定义弹出窗口

    网页上默认的提示框或对话框一般比较丑,可以利用div遮盖层来自定义对话框 1.定义一个按钮或者链接(项目里面是通过点击一个图片) <img src="images/zz.gif&quo ...

  9. PHP给图片加文字水印

    <?php /*给图片加文字水印的方法*/ $dst_path = 'http://f4.topitme.com/4/15/11/1166351597fe111154l.jpg'; $dst = ...

  10. Codeforces 486B - OR in Matrix

    矩阵的 OR ,也是醉了. 题目意思很简单,就是问你有没有这么一个矩阵,可以变化,得到输入的矩阵. 要求是这个矩阵每行都可以上下任意移动,每列都可以左右任意移动. 解题方法: 1.也是导致我WA 的原 ...