WCF服务编程(7)——配置元数据交换终结点

一、引言

我们也可以通过配置元数据交换终结点的方式来启用元数据交换。标准的元数据交换终结点的配置结构如下:

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

和普通的终结点类似,它也包含3个主要元素:契约(contract)、绑定(binding)和地址(address)。Address的配置和普通终结点的地址配置类似,可以配置为空、相对uri和带基地址的uriBinding类型为固定的几个类型,常见的有mexHttpBindingmexTcpBinding等等。Contract固定为IMetadataExchange。该契约接口已经由WCF自动为我们实现,但是我们在配置文件中必须为服务明确的指定该行为,否则启动服务时将会报错,如下所示:

         <behaviors>

            <serviceBehaviors>

                <behavior name="mex">

                    <serviceMetadata/>

                    <serviceDebug includeExceptionDetailInFaults="false" />

                </behavior>

            </serviceBehaviors>

        </behaviors>

        <services>

            <service name="WindowsFormsApplication11.Service1" behaviorConfiguration="mex">

                ...

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

                

                <host>

                    <baseAddresses>

                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/WindowsFormsApplication11/Service1/" />

                        <add baseAddress="net.tcp://localhost:8001/Service1/" />

                    </baseAddresses>

                </host>

            </service>

我们必须为服务指定定义了serviceMetadata标签的behavior,这样才是引入WCF自动实现的IMetadataExchange接口。否则,启动服务时将会报错。

二、添加默认的元数据终结点

上述方式,我们显式的添加了一个元数据终结点。其实,我们在配置中还可以通过endpoint标签的kind属性添加默认的元数据终结点。

如下面,我们添加了一个采用默认http类型基地址作为访问地址的元数据终结点:

   <endpoint address="mex1" kind="mexEndpoint"/>

如果我们需要添加其他类型基地址的元数据终结点,则在终结点中添加对应的binding,如添加支持net.tcp类型的基地址的元数据终结点:

   <endpoint address="mex1" kind="mexEndpoint" binding="mexTcpBinding"/>

WCF根据设置的binding类型推测出了基地址,从而构建了终结点的地址。

三、以编程的方式添加元数据终结点

  我们也可以在打开宿主之前,通过编码的方式添加元数据交换终结点。但是WCF并没有为元数据终结点提供专门的绑定类型,而是需要我们调用静态类MetadataExchangeBindings的相关静态方法创建binding,如使用CreateMexHttpBinding()创建mexHttpBinding类型的绑定,使用CreateMexTcpBinding()创建mexTcpBinding类型的绑定等等。如下面的代码:      

                        ServiceHost host = new ServiceHost(typeof(Service1));
            ServiceMetadataBehavior metadataBehavior;
            metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (metadataBehavior == null)
            {
                metadataBehavior = new ServiceMetadataBehavior();
                host.Description.Behaviors.Add(metadataBehavior);
            }
            System.ServiceModel.Channels.Binding binding = MetadataExchangeBindings.CreateMexHttpBinding();
            host.AddServiceEndpoint(typeof(IMetadataExchange), binding, "Mex");
            host.Open();

我们可以发现,与之前利用代码方式启用HTTP-GET协议终结点的唯一区别在于前者设置了metadataBehaviorHttpGetEnabledtrue,而这里调用了hostAddServiceEndpoint()的方法添加终结点。

以编程方式添加元数据终结点的另一种方法是使用标准元数据终结点(ServiceMetadataEndpoint),如下代码:

                        ServiceHost host = new ServiceHost(typeof(Service1));
            ServiceMetadataBehavior metadataBehavior;
            metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (metadataBehavior == null)
            {
                metadataBehavior = new ServiceMetadataBehavior();
                host.Description.Behaviors.Add(metadataBehavior);
            }
                 EndpointAddress address = new EndpointAddress("http://localhost:8001/service1/mex");
            ServiceEndpoint endpoint = new ServiceMetadataEndpoint(address);
            host.AddServiceEndpoint(endpoint);
            host.Open();

  从上面的代码可以看出,我们首先创建了一个ServiceMetadataEndpoint,并在创建该对象时传入一个EndpointAddress 对象,由于我们没有传入Binding对象,所以WCF推测默认binding类型为mexHttpBinding,也就是说此时我们提供的基地址必须采用http协议,否则应提供不同类型的binding。创建完一个ServiceMetadataEndpoint对象之后,利用hostAddServiceEndpoint方法将该元数据终结点进行添加。

 

 

    

 

 


评论