代码改变世界

WCF 第五章 导出并发布元数据(服务行为)

2010-12-07 08:37  DanielWise  阅读(1300)  评论(0编辑  收藏  举报

一个服务的ABCs-它的地址,绑定和契约-是以元数据的形式表示的以便于潜在的客户端知道到哪里,该如何与谁去通信。信息统称为服务元数据。服务行为元数据是大多数程序员遇到的第一个行为,因为当你创建WCF工程时它被引用于由Visual Studio 2008生成的配置文件里。这个行为与一个元数据终结点一起工作以便于元数据可以被客户端访问。

  为了使元数据对客户端有用,有两个步骤是必须的: 以一种客户端可读并发布到客户端可以找到的地方格式导出。默认的导出格式是WSDL,所以只要客户端可以读基于标准的元数据格式,它们可以理解如何与服务端通信。WCF在任何支持的传输协议上使用WS-MetadataExchange协议来发布元数据,或者它可以再对一个HTTP GET的反馈中发布元数据。这两个步骤,导出以及发布元数据,都是由一个服务中的ServiceMetadataBehavior实现的。

  元数据通过一个元数据交换节点(MEX)暴露出来。一个MEX终结点与任何其他WCF终结点类似: 它有一个地址,一个帮顶和一个契约。像任何其他终结点一样,一个MEX终结点可以通过配置文件或代码添加到服务中。

  一个MEX终结点应该暴露IMetadataExchange接口作为它的契约。定义在System.ServiceModel.Description,这个接口提供方法来检测一个服务并以WSDL格式暴露它的原数据。对MEX终结点来说有很多系统提供的绑定支持它,比如mexHttpBinding, mexHttpsBinding, mexNamedPipeBinding或者mexTcpBinding.一个MEX终结点的地址可以是相对的也可以是绝对的,在普通终结点地址的后面添加。

  列表5.13想爱你试了使用serviceMetadata行为定义并暴露元数据的一个配置文件。行为包含httpGetEnabled="True",指导WCF在终结点上不仅对WS-MEX 请求反馈也对HTTP GET 请求反馈。

  服务契约包含了一个暴露一个IMetadataExchange接口的终结点。这个终结点使用相对地址,使用HTTP传输协议,所以终结点的相对地址是http://localhost:8000/EssentialWCF/mex.终结点使用mexHttpBinding,它创建一个不支持安全特性的wsHttpBinding.

列表5.13 通过serviceMetadata使能元数据发布的配置文件

列表5.14 显示了一个

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings />
    <behaviors>
      <serviceBehaviors>
        <behavior name="myBehavior">
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="myBehavior" name="EssentialWCF.StockService">
        <endpoint address="" binding="basicHttpBinding" contract="EssentialWCF.IStockService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/EssentialWCF" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

暴露元数据的自我寄宿服务。它在功能上等同于5.13中的配置文件

列表5.14 使用ServiceMetadataBehavior来使能元数据发布的自我寄宿代码

    [ServiceContract]
    public interface IStockService
    {
        [OperationContract]
        double GetPrice(string ticker);
    }

    public class StockService : IStockService
    {
        public double GetPrice(string ticker)
        {
            return 94.85;
        }
    }
    public class Service
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(StockService), new Uri("http://localhost:8000/EssentialWCF"));
            host.AddServiceEndpoint(typeof(IStockService), new BasicHttpBinding(), "");
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            host.Description.Behaviors.Add(behavior);
            host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

            host.Open();
            Console.WriteLine("Service is started, press Enter to terminate");
            Console.ReadLine();
            host.Close();
        }
    }