How to: Publish Metadata for a Service Using a Configuration File

This is one of two how-to topics that demonstrate publishing metadata for a Windows Communication Foundation (WCF) service. There are two ways to specify how a service should publish metadata, using a configuration file and using code. This topic shows how to publish metadata for a service using a configuration file.

Caution

This topic shows how to publish metadata in an unsecure manner. Any client can retrieve the metadata from the service. If you require your service to publish metadata in a secure manner, see Custom Secure Metadata Endpoint.

For more information about publishing metadata in code, see How to: Publish Metadata for a Service Using Code. Publishing metadata allows clients to retrieve the metadata using a WS-Transfer GET request or an HTTP/GET request using the ?wsdl query string. To be sure that the code is working, create a basic WCF service. For simplicity, a basic self-hosted service is provided in the following code.

using System;  
using System.Runtime.Serialization;  
using System.ServiceModel;  
using System.ServiceModel.Description;  
  
namespace Metadata.Samples  
{  
    [ServiceContract]  
    public interface ISimpleService  
    {  
        [OperationContract]  
        string SimpleMethod(string msg);  
    }  
  
    class SimpleService : ISimpleService  
    {  
        public string SimpleMethod(string msg)  
        {  
            Console.WriteLine("The caller passed in " + msg);  
            return "Hello " + msg;  
        }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            ServiceHost host = new ServiceHost(typeof(SimpleService),  
                new Uri("http://localhost:8001/MetadataSample"));
            try  
            {  
                // Open the service host to accept incoming calls  
                host.Open();  
  
                // The service can now be accessed.  
                Console.WriteLine("The service is ready.");  
                Console.WriteLine("Press <ENTER> to terminate service.");  
                Console.WriteLine();  
                Console.ReadLine();  
  
                // Close the ServiceHostBase to shutdown the service.  
                host.Close();  
            }  
            catch (CommunicationException commProblem)  
            {  
                Console.WriteLine("There was a communication problem. " + commProblem.Message);  
                Console.Read();  
            }  
        }  
    }  
}  

This service is a self-hosted service, which is configured using a configuration file. The following configuration file serves as a starting point.

<configuration>  
  <system.serviceModel>  
    <services>  
      <service name="Metadata.Example.SimpleService">  
        <endpoint address=""  
                  binding="basicHttpBinding"  
                  contract="Metadata.Example.ISimpleService" />  
      </service>  
    </services>  
    <behaviors>  
  
    </behaviors>  
  </system.serviceModel>  
</configuration>  

To publish metadata for a WCF service using an application configuration file

  1. Within the App.config file, after the closing </services> element, create a <behaviors> element.

  2. Within the <behaviors> element, add a <serviceBehaviors> element.

  3. Add a <behavior> element to the <serviceBehaviors> element and specify a value for the name attribute of the <behavior> element.

  4. Add a <serviceMetadata> element to the <behavior> element. Set the httpGetEnabled attribute to true and the policyVersion attribute to Policy15. httpGetEnabled allows the service to respond to metadata requests made by an HTTP GET request. policyVersion tells the service to conform to WS-Policy 1.5 when generating metadata.

  5. Add a behaviorConfiguration attribute to the <service> element and specify the name attribute of the <behavior> element added in step 1, as shown in the following code example.

    <services>  
      <service  
          name="Metadata.Example.SimpleService"  
          behaviorConfiguration="SimpleServiceBehavior">  
        ...  
      </service>  
    </services>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="SimpleServiceBehavior">  
          <serviceMetadata httpGetEnabled="True" policyVersion="Policy15" />  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
    
  6. Add one or more <endpoint> elements with the contract set to IMetadataExchange, as shown in the following code example.

    <services>  
      <service  
          name="Metadata.Example.SimpleService"  
          behaviorConfiguration="SimpleServiceBehavior">  
    
        <endpoint address=""  
                  binding="wsHttpBinding"  
                  contract="Metadata.Example.ISimpleService" />  
    
        <endpoint address="mex"  
                  binding="mexHttpBinding"  
                  contract="IMetadataExchange" />  
      </service>  
    </services>  
    
  7. For the metadata endpoints added in the previous step, set the binding attribute to one of the following:

    • mexHttpBinding for HTTP publication.

    • mexHttpsBinding for HTTPS publication.

    • mexNamedPipeBinding for named pipe publication.

    • mexTcpBinding for TCP publication.

  8. For the metadata endpoints added in a previous step, set the address equal to:

    • An empty string to use the host application's base address as the publication point if the base address is the same as the metadata binding.

    • A relative address if the host application has a base address.

    • An absolute address.

  9. Build and run the console application.

  10. Browse to the base address of the service (http://localhost:8001/MetadataSample in this sample) and verify that the metadata publishing is turned on. If not, a message at the top of the resulting page displays: "Metadata publishing for this service is currently disabled."

To use default endpoints

  1. To configure metadata on a service that uses default endpoints, specify the ServiceMetadataBehavior in the configuration file as in the previous example, but do not specify any endpoints. The configuration file would then look like this.

    <configuration>  
      <system.serviceModel>  
        <behaviors>  
          <serviceBehaviors>  
            <behavior name="SimpleServiceBehavior">  
              <serviceMetadata httpGetEnabled="True" policyVersion="Policy12" />  
            </behavior>  
          </serviceBehaviors>  
        </behaviors>  
    
      </system.serviceModel>  
    </configuration>  
    

    Because the service has a ServiceMetadataBehavior with the httpGetEnabled set to true, the service has publishing metadata enabled, and because no endpoints were explicitly added, the runtime adds the default endpoints. For more information about default endpoints, bindings, and behaviors, see Simplified Configuration and Simplified Configuration for WCF Services.

Example

The following code example shows the implementation of a basic WCF service and the configuration file that publishes metadata for the service.

using System;  
using System.Runtime.Serialization;  
using System.ServiceModel;  
using System.ServiceModel.Description;  
  
namespace Metadata.Samples  
{  
    [ServiceContract]  
    public interface ISimpleService  
    {  
        [OperationContract]  
        string SimpleMethod(string msg);  
    }  
  
    class SimpleService : ISimpleService  
    {  
        public string SimpleMethod(string msg)  
        {  
            Console.WriteLine("The caller passed in " + msg);  
            return "Hello " + msg;  
        }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            ServiceHost host = new ServiceHost(typeof(SimpleService),  
                new Uri("http://localhost:8001/MetadataSample"));
            try  
            {  
                // Open the service host to accept incoming calls  
                host.Open();  
  
                // The service can now be accessed.  
                Console.WriteLine("The service is ready.");  
                Console.WriteLine("Press <ENTER> to terminate service.");  
                Console.WriteLine();  
                Console.ReadLine();  
  
                // Close the ServiceHostBase to shutdown the service.  
                host.Close();  
            }  
            catch (CommunicationException commProblem)  
            {  
                Console.WriteLine("There was a communication problem. " + commProblem.Message);  
                Console.Read();  
            }  
        }  
    }  
}  
<configuration>  
  <system.serviceModel>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="SimpleServiceBehavior">  
          <serviceMetadata httpGetEnabled="True" policyVersion="Policy12" />  
          <serviceDebug includeExceptionDetailInFaults="False" />  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
  </system.serviceModel>  
</configuration>  

See also