WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]
原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]
元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-MEX和HTTP-GET的元数据发布,针对这两种不同的协议,元数据获取的实现方式也是不同的。我们首先来实现基于WS-MEX的元数据获取方式。 [Source Code从这里下载]
一、 基于WS-MEX的元数据获取
ServiceMetadataBehavior通过创建MEX终结点实现了基于WS-MEX的元数据的发布,从《如何将一个服务发布成WSDL》系列文章的介绍我们知道:元数据的发布实际上可以看成是在服务端寄宿一个元数据提供服务,我们通过服务调用的形式获取元数据。
由于MEX终结点与一般意义上的终结点并没有本质的不同,我们只需要创建服务元数据发布方相匹配的终结点,相目标地址发送期望的请求消息,即可通过回复消息的形式获取元数据信息。现在以我们熟悉的计算服务为例,在服务寄宿的时候通过以下的配置为该服务添加一个MEX终结点,采用的MEX绑定和地址分别问:mexHttpBinding和http://127.0.0.1:9999/calculatorservice/mex。
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <system.serviceModel>
4: <services>
5: <service name="Artech.MetataRetrieval.Services.CalculatorService" behaviorConfiguration="mexBehavior">
6: <endpoint address=" http://127.0.0.1:9999/calculatorservice" binding="ws2007HttpBinding" contract="Artech.MetataRetrieval.Services.ICalculator"/>
7: <endpoint address="http://127.0.0.1:9999/calculatorservice/mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
8: </service>
9: </services>
10: <behaviors>
11: <serviceBehaviors>
12: <behavior name="mexBehavior">
13: <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:3721/calculatorservice/metadata"/>
14: </behavior>
15: </serviceBehaviors>
16: </behaviors>
17: </system.serviceModel>
18: </configuration>
下面的代码展现了客户端获取元数据的程序,这和一般的服务调用并无二致。首先通过指定相应的绑定(MetadataExchangeBindings.CreateMexHttpBinding())和地址(元数据的目标地址:http://127.0.0.1:9999/calculatorservice/mex)创建ChannelFactory<TChannel>对象(由于MEX终结点契约类型为IMetadataExchange,这里的TChannel类型为IMetadataExchange)。由于MEX终结点契约IMetadataExchange的Get方法的输入参数和输出参数均为Message对象,而是我们创建Message对象,并指定与WS-MEX匹配的Action。然后传入通过ChannelFactory<TChannel>创建的服务代理中进行服务调用。最后从回复消息中提取出包含元数据的MetadataSet对象,并将其写入一个XML文件中。
1: using System;
2: using System.Diagnostics;
3: using System.ServiceModel;
4: using System.ServiceModel.Channels;
5: using System.ServiceModel.Description;
6: using System.Text;
7: using System.Xml;
8: namespace Artech.MetataRetrieval
9: {
10: class Program
11: {
12: static void Main(string[] args)
13: {
14: MetadataSet metadata = null;
15: using (ChannelFactory<IMetadataExchange> channelFactory = new ChannelFactory<IMetadataExchange>(MetadataExchangeBindings.CreateMexHttpBinding(), new EndpointAddress("http://127.0.0.1:9999/calculatorservice/mex")))
16: {
17: IMetadataExchange proxy = channelFactory.CreateChannel();
18: using (proxy as IDisposable)
19: {
20: Message request = Message.CreateMessage(MessageVersion.Default, "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get");
21: metadata = proxy.Get(request).GetBody<MetadataSet>();
22: }
23: }
24: using (XmlWriter writer = new XmlTextWriter("metadata.xml", Encoding.UTF8))
25: {
26: metadata.WriteTo(writer);
27: }
28: Process.Start("metadata.xml");
29: }
30: }
31: }
当程序成功执行,包含元数据的XML文件将会通过IE输出(假设将IE作为默认的XML启动程序),图1为运行后的截图。
图1 通过IE显示获取的元数据(以WS-MEX方式发布)
二、 基于HTTP-GET的元数据获取
上面我们通过自定的方式成功获取了服务端以WS-MEX方式发布的元数据,现在我们来是实现基于HTTP-GET的元数据获取方式。既然服务端采用了基于HTTP-GET的元数据发布方式,那么就意味着我们可以通过简单的HTTP请求的方式获取相应的元数据资源。
同样是基于上面的例子,仔细的读者相信已经看到了,在计算服务的配置文件中,除了为服务添加MEX终结点之外,还通过ServiceMetadataBehavior开启了基于HTTP-GET的元数据发布方式,并将元数据发布地址指定为:http://127.0.0.1:3721/calculatorservice/metadata。
下面的代码实现了相应的元数据获取,其中我通过指定目标地址创建了一个HttpWebRequest对象,并通过该对象向元数据的发布地址发送请求。获取的元数据将以HttpWebResponse的形式返回,由于获取的元数据实际上是一个WSDL文档,所以我们可以通过ServiceDescription的Read方法直接读取生成一个ServiceDescription对象,并最终通过MetadataSection的静态方法CreateFromServiceDescription将其转换成一个MetadataSection对象。该MetadataSection对象被最终添加到创建的MetadataSet中,并被写入一个XML文件。
1: using System.Diagnostics;
2: using System.Net;
3: using System.ServiceModel.Description;
4: using System.Xml;
5: using System.Text;
6: namespace Artech.MetataRetrieval
7: {
8: class Program
9: {
10: static void Main(string[] args)
11: {
12: MetadataSet metadata = new MetadataSet();
13: HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:3721/calculatorservice/metadata");
14: request.Method = "Get";
15: HttpWebResponse response = (HttpWebResponse)request.GetResponse();
16: using (XmlReader reader = XmlDictionaryReader.CreateTextReader(response.GetResponseStream(), new XmlDictionaryReaderQuotas()))
17: {
18: System.Web.Services.Description.ServiceDescription serviceDesc = System.Web.Services.Description.ServiceDescription.Read(reader);
19: metadata.MetadataSections.Add(MetadataSection.CreateFromServiceDescription(serviceDesc));
20: }
21: using (XmlWriter writer = new XmlTextWriter("metadata.xml", Encoding.UTF8))
22: {
23: metadata.WriteTo(writer);
24: }
25: Process.Start("metadata.xml");
26: }
27: }
28: }
当上面的应用程序成功执行,包含获取的元数据的XML将会通过IE打开,图2为运行后的截图。通过两种方式获取的元数据本质上是相同的,不过可能细心的读者已经发现了:与上面的例子(WS-MEX)获取的MetadataSet不同,通过HTTP-GET获取的MetadataSet仅仅包含一个元数据方言(Dialect)为WSDL的MetadataSection。这是因为,前面的例子实际上将WSDL中引用(通过终结点地址或者资源地址)的内容都生成了相应的MetadataSection,在这里由于篇幅所限,并没有做这些工作。
图2 通过IE显示获取的元数据(以HTTP-GET方式发布)
出处:http://artech.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]的更多相关文章
- WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]
原文:WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载] 我们有两种典型的WCF调用方式:通过SvcUtil.exe(或者添加Web引用)导入发布的服务元数据生成服务代理相关的代码 ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇] 通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]
原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇] 在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Tra ...
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...
- WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?
原文:WCF技术剖析之二十: 服务在WCF体系中是如何被描述的? 任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过 ...
- WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)
原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...
- WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序)
原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序) 通过<如何将一个服务发布成WSDL[编程篇]>的介绍我们知道了如何可以通过编程或者配 ...
随机推荐
- Sass入门——简介+语法格式及编译调试
本文来自慕课网大漠. Sass简介 Sass和SCSS区别 1.后缀名不同,很好理解 2.Sass以严格的缩进语法规则书写,不带大括号和分号:而SCSS的语法规则和CSS的语法很类似. Sass: $ ...
- C#中字符串的处理,对象的引用及继承(Tenth day)
又进入到了新的一周,现在到总结的时间了,继续为大家总结一下今天在云和学院所学的知识. 理论: StringBuilder 和 String 的区别 String 在进行运算时(如赋值.拼接等)会 ...
- C#编辑基础笔记
目录 1. .NET .NET Framework是一种多语言的平台,一种技术. 而c#是基于其上面的一种语言. 1 2. Winform 桌面应用程序[从.net平台上面开发的 ...
- C# Best Practices - Handling Strings
Features Strings Are Immutable. A String Is a Reference Type Value Type Store their data directly Ex ...
- What day is that day?(快速幂,打表找周期,或者求通项公式)
有些题怎么都解不出来,这时候可以打表,找规律,求通项公式等,这些方法让人拍手叫绝,真不错…… Description It's Saturday today, what day is it after ...
- centos安装epel源
用163的源,但是我发现这个源里面,根本没有libmcrypt libmcrypt-devel这二个包,装php扩展mcrypt时,又要用到这二个包,所以我手动装了libmcrypt包,但是给我的感觉 ...
- [LeetCode]题解(python):058-Length of Last Word
题目来源: https://leetcode.com/problems/length-of-last-word/ 题意分析: 给出只包括大小写和空格的字符,输出最后一个单词的长度. 题目思路: 从最后 ...
- LinkList Operation
链表典型数据结构: #define ElemType int typedef struct LinkNode{ ElemType value; struct LinkNode* next; }; 相比 ...
- 关于map
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap. Map主要用于存储健值对, ...
- 《Clean Code》重点内容总结
读书笔记请见Github博客:http://wuxichen.github.io/Myblog/reading/2014/10/06/CleanCode.html