参考:http://blog.csdn.net/songyefei/article/details/7397296

元数据交换

通过前两篇的学习,我们了解了WCF通信的一些基本原理,我们知道,WCF服务端和客户端通过共享元数据(包括服务协定、服务器终结点信息)在两个终结点上建立通道从而进行通信。我们通过手写代码(或配置)的方式为服务端编写了元数据信息,没有借助元数据交换就实现了通信。然而在实际应用中,元数据往往是很多的,而且重复编写元数据的工作也是不值得的,因此必然会用到元数据交换的方式让客户端获取元数据,本篇我们就来进一步了解一下元数据和元数据交换。

1. 元数据是怎样提供的

我们知道,元数据包括了要和服务端进行通信的所有信息,包括服务协定接口、服务端终结点地址、绑定等信息,它指出了客户端应该到何处去寻找服务以及怎样调用服务的一切线索。但是服务端是怎样公布其元数据的呢?
    答案是使用WSDL文件,WSDL即Web Service Description Language,Web服务描述语言,它是一个XML文件,在这个文件中按照一定的标准来对Web Service进行描述,他是符合W3C标准的,因为WCF是被设计为供不同平台调用的服务框架,所以客户端可能是非微软平台的,比如Java什么的。因此WCF必须使用WSDL这种国际标准的描述方法来描述服务才能被众多的平台所访问。

2. 元数据交换的过程是怎样的

在WCF服务端的运行时,有一组类库随时待命把服务的元数据输出为WSDL描述提供给请求者,只要有客户端按照服务端约定的方法来请求元数据,服务端立即将服务运行时状态写成WSDL文件提供。客户端得到的实际上就是WSDL文件(还有一些框架描述文件XSD),客户端拿到文件后再使用自己的方法来解读WSDL,把他翻译成客户端可用的源代码或配置文件,这时客户端就得到了服务的编程模型,通过一些代理类,客户端甚至可以像调用本地对象一样使用WCF服务。

因此整个过程是这样:客户端向服务端请求元数据交换-->服务端运行时将元数据编写成WSDL文件提供-->客户端获得文件-->客户端翻译文件-->客户端根据翻译结果生成本地类代码和配置-->客户端获得服务的本地编程模型。这就是元数据交换的过程。

3. 获得WSDL

在微软平台中,有两种方法来进行元数据交换,第一是使用服务引用,第二是使用元数据实用工具(svcutil.exe)来进行,我们先学习这个工具。

这个工具可以在Windows SDK中找到,具体位置为 C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin,如果你有VS2010,可以启动VS2010的命令行工具,这样就可以在任何目录下使用这个程序。

我们先看一个例子,就是我们在前几篇中建立的IIS服务HelloWCFService,它被我寄宿在IIS中。

源代码如下(HelloWCF.cs):

using System;
using System.ServiceModel; namespace LearnWCF
{
[ServiceContract]
public interface IHelloWCF
{
[OperationContract]
string HelloWCF();
} public class HelloWCFService : IHelloWCF
{
public string HelloWCF()
{
return "Hello WCF!";
}
}
}

配置文件(web.config)如下:

    <configuration>
<system.serviceModel>
<services>
<service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange">
<endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataExchange">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

在浏览器中输入服务地址会如下图所示:

看到系统提示的那行命令了么?系统在告诉我们如何使用svcutil.exe来获得元数据。我们现在试一下,首先打开VS2010命令行:

开始-->所有程序-->Visual Studio 2010-->Visual Studio Tools-->Visual Studio命令行提示

我们导航到一个目录下准备获得元数据文件。

我们暂时不按照浏览器提供给我们的方法做,因为按照那个方法做就把获得WSDL和翻译WSDL为客户端代码合在一起了,我们先获得WSDL元数据文件,看看它是什么样子的。我们按如下的指令做:

svcutil.exe /t:metadata http://localhost/iisservice/hellowcfservice.svc?wsdl

我们加入了一个参数/t:metadata 表示只输出元数据,不生成代码。命令的执行过程如下:

可以看到生成了3个文件,包括两个架构文件和一个WSDL文件,这些就是服务端元数据的描述了,所有的客户端请求到的实际上都是这个文件。WSDL的规范比较多,关于它的内容,我们今后再展开来看,不过简单的打开看一下就能看出一些与服务协定、绑定、操作这些东西相关的地方。

4. 翻译WSDL文件

WSDL是一个XML文件,其实就是个文本文件,客户端必须将其按照自己的平台特点把他翻译成本地代码文件来使用。svcutil当然会提供这个功能。在wsdl文件所在目录下使用如下的命令就可以把WSDL文件翻译成本地代码文件:

svcutil *.wsdl *.xsd

顾名思义,就是根据当前目录下的所有的WSDL文件和XSD文件来生成客户端代码文件。过程会是这样

可以看到,生成了一个cs文件和一个配置文件,这些就是根据WSDL文件翻译成的客户端代码文件了。打开来看看,一定不陌生,就是使用ClientBase<>来生成一个客户端代理类并把终结点的信息配置在了.config文件里。把这两个文件包含在客户端的项目中并把output.config改成app.config就可以了。

4. 更好地使用元数据交换工具

之前我们了解了使用svcuitl.exe来获取WSDL并翻译成客户端代码的过程。实际上这两步可以合二为一。直接执行下面的命令可以直接获得客户端文件:

svcutil.exe http://localhost/iisservice/hellowcfservice.svc?wsdl

这样它就不会生成WSDL而直接生成客户端文件了。

不过按照这样的方式生成的文件可能不太符合我们的要求,我们可以加上一些参数来指定我们输出的文件名:

svctuil.exe /out:ClientProxy.cs /config:app.config http://localhost/iisservice/hellowcfservice.svc?wsdl

这样输出的文件我们就可以直接包含在客户端项目中使用了。

5. 使用服务引用

其实使用服务引用跟使用svcutil.exe生成的客户端模型是一样的,不过服务引用保留了WSDL文件(以及一些相关的七七八八的文件),没有svcutil.exe来得那么清爽,但是它跟VS2010集成,使用起来很简单,而且当服务发生变化时,只需要右击服务引用选择更新服务就可以重新下载WSDL了

6. 展开一点点

作为服务端,公开元数据是需要配置的,不同的配置会导致元数据公开的方式不同。

我们要记住,WCF服务端公开元数据必须具备两个条件:

(1) 为服务添加ServiceMetadata行为。

(2) 打开元数据交换终结点。

二者缺一不可。

WCF的公开元数据的手段主要有两种:

第一种:通过HTTP GET方法。

这就是在前文中我们看到的方法,我们可以使用HTTP Get的方法来获得WSDL文件即在服务地址.svc后面跟上?wsdl的方法直接请求到WSDL文件。我们可以直接在浏览器中输入服务端地址.svc?wsdl,浏览器就直接获得了WSDL文件并为我们显示出来了。

还有相应的框架描述文件(XSD)

如果想采用这种元数据公开方式,必须配置服务的ServiceMetadata行为,并指定httpGetEnabled = "true",而元数据公开终结点不必配置,系统会自动配置一个,配置文件的写法如下:

    <configuration>
<system.serviceModel>
<services>
<service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange">
<endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataExchange">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

在这种配置下,访问元数据的方法是访问下面的地址:

http://localhost/iisservice/hellowcfService.svc?wsdl

第二种:通过MEX元数据交换终结点。

在这种方式下,我们首先要保证服务拥有ServiceMetadata行为,但是httpGetEnabled可以不必为true。此外我们还需要为服务显式地添加一个终结点,这个终结点的地址、绑定和协定都是指定的我们不能更改

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

配置文件的写法如下:

    <configuration>
<system.serviceModel>
<services>
<service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange">
<endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataExchange">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

如果按这种配置,我们必须按照如下地址来访问公开的元数据:

http://localhost/iisservice/hellowcfservice.svc/mex

注意,由于没有开启HTTP GET,我们不能在浏览器中直接输入这个地址来获取WSDL了(会提示400错误),我们必须通过svcutil.exe或添加服务引用的方式来访问。

使用svcutil.exe或服务引用的时候可以不关心元数据公开方式是HTTP GET还是Mex,他们会自动寻找到合适的方式,只需要把服务的svc文件地址输入就可以了,但是我们应该知道,这两种元数据公开的方式是有区别的。

6. 总结

通过今天的学习,我们进一步了解了WCF元数据的和元数据交换的原理。虽然我们在实际工程中都会并且应该使用元数据交换工具来帮助提高效率,但是这背后发生的所有环节也是我们应该掌握的。

相关资源

MSDN关于Svcutil.exe用法的文档

http://msdn.microsoft.com/zh-cn/library/aa347733.aspx

初识WCF6的更多相关文章

  1. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  2. 初识Hadoop

    第一部分:              初识Hadoop 一.             谁说大象不能跳舞 业务数据越来越多,用关系型数据库来存储和处理数据越来越感觉吃力,一个查询或者一个导出,要执行很长 ...

  3. python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)

    一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...

  4. 初识IOS,Label控件的应用。

    初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ...

  5. UI篇(初识君面)

    我们的APP要想吸引用户,就要把UI(脸蛋)搞漂亮一点.毕竟好的外貌是增进人际关系的第一步,我们程序员看到一个APP时,第一眼就是看这个软件的功能,不去关心界面是否漂亮,看到好的程序会说"我 ...

  6. Python导出Excel为Lua/Json/Xml实例教程(一):初识Python

    Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...

  7. 初识SpringMvc

    初识SpringMvc springMvc简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 s ...

  8. 初识redis数据类型

    初识redis数据类型 1.String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据 ...

  9. Redis初识、设计思想与一些学习资源推荐

    一.Redis简介 1.什么是Redis Redis 是一个开源的使用ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的API.从2010 年 ...

随机推荐

  1. Mac 10.12安装流量监控软件Magican

    说明:Magican这家公司已经不维护了,但是软件是单机版的,可以正常使用,但是有些10.12的机器应该是无法看到每个进程的明细,总速度可以正常显示. 下载: (链接: https://pan.bai ...

  2. 用python开发了一个简单apache web服务端范例,在win10 + apache2.4.9 + python3.5 测试成功

    #!D:\Programs\Python\Python35-32\python.exe import cgi def htmlTop():     print("Content-type: ...

  3. 自定义类型转换器之TypeConverter

    C#提供了很多类型转换的方法如ConvertToInt.int.Parse.int.tryParse等等,这些方法都能将一个C#的基本数据类型转换成另一个C#基本数据类型.那么.既然如此,C#肯定会提 ...

  4. struts2 servlet之间通信

    Servlet之间通信的方式有两大类,每个类有三种不同的方法 1.request 2.session 3.application 不实现ServletContextAware,SessionAware ...

  5. class对象存储

    当加载一个类完成后,会在内存中实例化一个java.lang.Class类的对象,也就是该类的类对象.但是并没有明确规定必须在java堆中存放该类对象,对于HotSpot虚拟机而言,类对象存放在方法区里 ...

  6. 07 volatile & java 内存模型

    一 从单例模式说起 在singleton 单例模式一文中我们详细了解Java中单例模式的实现,不了解的可以先阅读之. 在该文最后我们给出了双重校验锁来保证既实现线程安全,又能够使性能不受很大的影响的单 ...

  7. 码表的理解(ASCII,GBK,Unicode,UTF-8等)。

    以下任何言论都完全是个人的理解,如有雷同纯属巧合,如有错误,希望大家多多指出,共同学习!谢谢! 笔者是一个理解能力偏慢.稍钻牛角尖的程序员,什么东西都要从最基础理解起,一步一步向上理解,因此讲述时也是 ...

  8. MTCNN 实现人脸识别

    MTCNN(Multi-task CNN) MTCNN难点 WIDER FACE等数据集为我们提供的图片并不是MTCNN支持的训练样本, 需要通过几个脚本将其转为MTCNN可以接受的数据集, 这些脚本 ...

  9. [PY3]——基本语法

    Python3基本语法-xmind图 常量/变量 1. 常量:一旦赋值就不可再改变.不能对它重新赋值.python不存在常量2. 字面常量:一个单独出现的量,未赋值给任何变量或常量3. 变量: i=3 ...

  10. 如何用webgl(three.js)搭建不规则建筑模型,客流量热力图模拟

    本节课主要讲解如何用webgl(three.js)搭建一个建筑模型,客流量热力图模拟 使用技术说明: 这里主要用到了three.js,echart.js以及一些其它的js 与css技术,利用webso ...