Windows Communication Foundation (WCF)提供了丰富的基础结构,用于导出、发布、检索和导入服务元数据。 WCF 服务使用元数据描述如何与服务的终结点交互,以便工具(如 Svcutil.exe)可以自动生成用于访问服务的客户端代码。
构成 WCF 元数据基础结构的大多数类型驻留在命名空间中 System.ServiceModel.Description 。
WCF 使用 ServiceEndpoint 类来描述服务中的终结点。 可以使用 WCF 为服务终结点生成元数据,或导入服务元数据来生成 ServiceEndpoint 实例。
WCF 将服务的元数据表示为类型的实例 MetadataSet ,其结构与 WS-MetadataExchange 中定义的元数据序列化格式密切相关。 该 MetadataSet 类型将实际的服务元数据(如 Web 服务描述语言(WSDL)文档、XML 架构文档或 WS-Policy 表达式捆绑为实例集合 MetadataSection 。 每个 System.ServiceModel.Description.MetadataSection 实例都包含特定的元数据方言和标识符。 A System.ServiceModel.Description.MetadataSection 可以在其 MetadataSection.Metadata 属性中包含以下项:
原始元数据。
实例 MetadataReference 。
实例 MetadataLocation 。
System.ServiceModel.Description.MetadataReference实例指向另一个元数据交换(MEX)终结点,System.ServiceModel.Description.MetadataLocation实例使用 HTTP URL 指向元数据文档。 WCF 支持使用 WSDL 文档来描述服务终结点、服务协定、绑定、消息交换模式、消息和服务实现的错误消息。 服务的数据类型在 WSDL 文档中使用 XML 架构进行描述。 有关详细信息,请参阅 架构导入和导出。 可以使用 WCF 导出和导入用于扩展服务功能的服务行为、协定行为和绑定元素的 WSDL 扩展。 有关详细信息,请参阅 导出 WCF 扩展的自定义元数据。
导出服务元数据
在 WCF 中, 元数据导出 是描述服务终结点并将其投影到并行标准化表示形式的过程,客户端可以使用这些表示形式来了解如何使用该服务。 若要从 ServiceEndpoint 实例导出元数据,请使用抽象类的 MetadataExporter 实现。 System.ServiceModel.Description.MetadataExporter 实现生成的元数据被封装在 MetadataSet 实例中。
该 System.ServiceModel.Description.MetadataExporter 类提供了一个框架,用于生成策略表达式,用于描述终结点绑定的功能和要求及其关联的作、消息和错误。 这些策略表达式在PolicyConversionContext实例中被捕获。 然后, System.ServiceModel.Description.MetadataExporter 实现可以将这些策略表达式附加到生成的元数据。
当生成供 System.ServiceModel.Description.MetadataExporter 实现使用的 System.ServiceModel.Channels.BindingElement 对象时,IPolicyExportExtension 调入在 ServiceEndpoint 的绑定中实现 PolicyConversionContext 接口的每个 System.ServiceModel.Description.MetadataExporter。 可以通过在IPolicyExportExtension类型的自定义实现上实现BindingElement接口来导出新策略断言。
在 WCF 中,WsdlExporter 抽象类的实现是 System.ServiceModel.Description.MetadataExporter 类型。 该 WsdlExporter 类型使用附加的策略表达式生成 WSDL 元数据。
若要为服务终结点中的终结点行为、协定行为或绑定元素导出自定义 WSDL 元数据或 WSDL 扩展,可以实现接口 IWsdlExportExtension 。 在生成 WSDL 文档时,WsdlExporter 为实现 ServiceEndpoint 接口的绑定元素、操作行为、协定行为和终结点行为查看 IWsdlExportExtension 实例。
发布服务元数据
WCF 服务通过公开一个或多个元数据终结点来发布元数据。 发布服务元数据使服务元数据可以使用标准化协议(如 MEX 和 HTTP/GET 请求)。 元数据终结点类似于其他服务终结点,因为它们具有地址、绑定和协定。 可以在配置或代码中将元数据终结点添加到服务主机。
要发布 WCF 服务的元数据终结点,您必须首先向服务添加一个 ServiceMetadataBehavior 服务行为的实例。 将System.ServiceModel.Description.ServiceMetadataBehavior实例添加到服务中可增强服务的功能,使其能够通过公开一个或多个元数据终结点来发布元数据。 添加 System.ServiceModel.Description.ServiceMetadataBehavior 服务行为后,您可以公开支持 MEX 协议的元数据终结点或响应 HTTP/GET 请求的元数据终结点。
若要添加使用 MEX 协议的元数据终结点,请将服务终结点添加到使用名为 IMetadataExchange 的服务协定的服务主机。WCF 定义具有此服务协定名称的 IMetadataExchange 接口。 WS-MetadataExchange 终结点或 MEX 终结点可以使用类上的 MetadataExchangeBindings 静态工厂方法公开的四个默认绑定之一来匹配 WCF 工具使用的默认绑定,例如 Svcutil.exe。 还可以使用自定义绑定配置 MEX 元数据终结点。
ServiceMetadataBehavior 使用 System.ServiceModel.Description.WsdlExporter 来导出服务中所有服务终结点的元数据。 有关从服务导出元数据的详细信息,请参阅 导出和导入元数据。
通过将 ServiceMetadataBehavior 实例作为服务主机的扩展添加,ServiceMetadataExtension 增强了服务主机。 System.ServiceModel.Description.ServiceMetadataExtension 提供了元数据发布协议的实现。 还可以通过 System.ServiceModel.Description.ServiceMetadataExtension 在运行时访问 Metadata 属性来获取服务的元数据。
谨慎
如果在应用程序配置文件中添加了 MEX 终结点,然后尝试在代码中将 ServiceMetadataBehavior 添加到服务主机中,则会出现以下异常:
System.InvalidOperationException:服务 Service1 实现的协定列表中找不到协定名称“IMetadataExchange”。 将 ServiceMetadataBehavior 添加到配置文件或直接添加到 ServiceHost,以启用对此协定的支持。
可以通过在配置文件中添加 ServiceMetadataBehavior,或在代码中同时添加终结点和 ServiceMetadataBehavior,来解决此问题。
有关在 ServiceMetadataBehavior 应用程序配置文件中添加的示例,请参阅 入门。 在代码中添加 ServiceMetadataBehavior 的示例,请参阅 自承载 示例。
谨慎
在发布一个公开两个不同服务契约的服务的元数据时,如果每个契约中都包含同名的操作,则会抛出异常。 例如,如果你有一个服务公开名为 ICarService 的服务协定(具有操作 Get(Car c)),并且同一服务公开名为 IBookService 的服务协定(具有操作 Get(Book b)),则会在生成服务的元数据时引发异常或显示错误消息。 若要解决此问题,请执行以下作之一:
检索服务元数据
WCF 可以使用标准化协议(如 WS-MetadataExchange 和 HTTP)检索服务元数据。 这两种协议都受 MetadataExchangeClient 该类型支持。 通过提供地址和可选绑定,可以使用 System.ServiceModel.Description.MetadataExchangeClient 类型检索服务元数据。
System.ServiceModel.Description.MetadataExchangeClient实例使用的绑定可能是MetadataExchangeBindings静态类中的默认绑定之一、用户提供的绑定,或从IMetadataExchange
契约的终结点配置中加载的绑定。
System.ServiceModel.Description.MetadataExchangeClient 也可以使用 HttpWebRequest 类型来解析 HTTP URL 对元数据的引用。
默认情况下,实例 System.ServiceModel.Description.MetadataExchangeClient 绑定到单个 ChannelFactoryBase 实例。 通过重写 ChannelFactoryBase 虚拟方法,您可以更改或替换由 System.ServiceModel.Description.MetadataExchangeClient 使用的 GetChannelFactory 实例。 同样,通过重写 System.Net.HttpWebRequest 虚拟方法,可以更改或替换由 System.ServiceModel.Description.MetadataExchangeClient 使用的 MetadataExchangeClient.GetWebRequest 实例以发出 HTTP/GET 请求。
可以使用 WS-MetadataExchange 或 HTTP/GET 请求来检索服务元数据,方法是使用 Svcutil.exe 工具并传递 /target:metadata 开关和一个地址。 Svcutil.exe 将元数据下载到指定的地址,并将文件保存到磁盘。 Svcutil.exe 在内部使用 System.ServiceModel.Description.MetadataExchangeClient 实例并加载 MEX 终结点配置(从应用程序配置文件),其名称与传递给 Svcutil.exe的地址方案匹配(如果存在)。 否则,Svcutil.exe 默认使用静态工厂类型定义的 MetadataExchangeBindings 绑定之一。
导入服务元数据
在 WCF 中,元数据导入是通过元数据生成服务或其组件抽象表示的过程。 例如,WCF 可以从服务的 WSDL 文档导入 ServiceEndpoint 实例、 Binding 实例或 ContractDescription 实例。 若要在 WCF 中导入服务元数据,请使用抽象类的 MetadataImporter 实现。 派生自 System.ServiceModel.Description.MetadataImporter 类的类型实现对导入利用 WCF 中 WS-Policy 导入逻辑的元数据格式的支持。
System.ServiceModel.Description.MetadataImporter实现收集附加到服务元数据中的策略表达式,并将其保存到PolicyConversionContext对象中。 然后,System.ServiceModel.Description.MetadataImporter通过调用IPolicyImportExtension属性中的PolicyImportExtensions接口的实现,在导入元数据时处理这些策略。
通过将自己的 System.ServiceModel.Description.MetadataImporter 接口实现添加到 IPolicyImportExtension 实例上的 PolicyImportExtensions 集合,可以添加对将新策略断言导入到 System.ServiceModel.Description.MetadataImporter 的支持。 或者,可以在客户端应用程序配置文件中注册策略导入扩展。
在 WCF 中,System.ServiceModel.Description.WsdlImporter 抽象类的实现是 System.ServiceModel.Description.MetadataImporter 类型。 System.ServiceModel.Description.WsdlImporter 类型可以导入含有附加策略(这些策略捆绑在 MetadataSet 对象中)的 WSDL 元数据。
可以通过实现 IWsdlImportExtension 接口,然后将你的实现添加到你的 WsdlImportExtensions 实例的 System.ServiceModel.Description.WsdlImporter 属性,来添加对导入 WSDL 扩展的支持。 System.ServiceModel.Description.WsdlImporter 还可以加载在客户端应用程序配置文件中注册的 System.ServiceModel.Description.IWsdlImportExtension 接口的实现。
动态绑定
如果终结点的绑定更改,或者希望为使用相同协定但具有不同绑定的终结点创建一个通道,则可以动态更新用来为服务终结点创建通道的绑定。 可以使用 MetadataResolver 静态类在运行时检索和导入实现特定协定的服务终结点的元数据。 然后可以使用导入的 System.ServiceModel.Description.ServiceEndpoint 对象为所需终结点创建客户端或通道工厂。