Export (0) Print
Expand All

How to: Publish Metadata for a Service Using Code

This is one of two how-to topics that discuss 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 code.

Caution note 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 a configuration file, see How to: Publish Metadata for a Service Using a Configuration File. 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 you must create a basic WCF service. 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;
        }
    }


To publish metadata in code

  1. Within the main method of a console application, instantiate a ServiceHost object by passing in the service type and the base address.

    
    ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost:8001/MetadataSample"));
    
    
    
  2. Create a try block immediately below the code for step 1, this catches any exceptions that get thrown while the service is running.

    
    try
    {
    
    
    
    
    }
    catch (CommunicationException commProblem)
    {
        Console.WriteLine("There was a communication problem. " + commProblem.Message);
        Console.Read();
    }
    
    
    
  3. Check to see whether the service host already contains a ServiceMetadataBehavior, if not, create a new ServiceMetadataBehavior instance.

    
    // Check to see if the service host already has a ServiceMetadataBehavior
    ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
    // If not, add one
    if (smb == null)
        smb = new ServiceMetadataBehavior();
    
    
    
  4. Set the HttpGetEnabled property to true.

    
    smb.HttpGetEnabled = true;
    
    
    
  5. The ServiceMetadataBehavior contains a MetadataExporter property. The MetadataExporter contains a PolicyVersion property. Set the value of the PolicyVersion property to Policy15. The PolicyVersion property can also be set to Policy12. When set to Policy15 the metadata exporter generates policy information with the metadata that” conforms to WS-Policy 1.5. When set to Policy12 the metadata exporter generates policy information that conforms to WS-Policy 1.2.

    
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
    
    
    
  6. Add the ServiceMetadataBehavior instance to the service host's behaviors collection.

    
    svcHost.Description.Behaviors.Add(smb);
    
    
    
  7. Add the metadata exchange endpoint to the service host.

    
    // Add MEX endpoint
    svcHost.AddServiceEndpoint(
      ServiceMetadataBehavior.MexContractName,
      MetadataExchangeBindings.CreateMexHttpBinding(),
      "mex"
    );
    
    
    
  8. Add an application endpoint to the service host.

    
    // Add application endpoint
    svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
    
    
    
    Note Note

    If you do not add any endpoints to the service, the runtime adds default endpoints for you. In this example, because the service has a ServiceMetadataBehavior set to true, the service has publishing metadata enabled. For more information about default endpoints, see Simplified Configuration and Simplified Configuration for WCF Services.

  9. Open the service host and wait for incoming calls. When the user presses ENTER, close the service host.

    
    // Open the service host to accept incoming calls
    svcHost.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.
    svcHost.Close();
    
    
    
  10. Build and run the console application.

  11. Use Internet Explorer to browse to the base address of the service (http://localhost:8001/MetadataSample in this sample) and verify that the metadata publishing is turned on. You should see a Web page displayed that says "Simple Service" at the top and immediately below "You have created a service." If not, a message at the top of the resulting page displays: "Metadata publishing for this service is currently disabled."

The following code example shows the implementation of a basic WCF service that publishes metadata for the service in 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 svcHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost:8001/MetadataSample"));
            try
            {
                // Check to see if the service host already has a ServiceMetadataBehavior
                ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
                // If not, add one
                if (smb == null)
                    smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                svcHost.Description.Behaviors.Add(smb);
                // Add MEX endpoint
                svcHost.AddServiceEndpoint(
                  ServiceMetadataBehavior.MexContractName,
                  MetadataExchangeBindings.CreateMexHttpBinding(),
                  "mex"
                );
                // Add application endpoint
                svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
                // Open the service host to accept incoming calls
                svcHost.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.
                svcHost.Close();
            }
            catch (CommunicationException commProblem)
            {
                Console.WriteLine("There was a communication problem. " + commProblem.Message);
                Console.Read();
            }
        }
    }
}


Show:
© 2014 Microsoft