How to do it: Expose WCF Service metadata information

Description and samples
Table of Contents
Description

By default WCF doesn’t expose metadata. It must be exposed explicitly via the service configuration file ou programatically at the host.

Operations
Enabling metadata expose through the exchange endpoint (MEX)
How to do it

The Metadata Exchange Endpoint (MEX) is a special endpoint in WCF that exposes metadata used to describe a service, where:

  • Address: It is an Uri to identify the metadata. Usually the endpoint address appended with “mex” keyword is used;
  • Binding: There are several bindings supported for metadata exchange to be used to the available transport protocols. Those are mexHttpBinding, mexHttpsBinding, mexNamedPipesBinding, and mexTcpBinding;
  • Contract: The IMetadataExchange is the contract used for MEX endpoint. WCF service host automatically provides the implementation for this IMetadataExchange while hosting the service.

The Metadata Exchange Endpoint can be defined either via the configuration file or programmatically.

Configuration file:

<services>
	<service name="TestService1">
	<endpoint address="http://localhost/training/TestService1.svc"
	binding="wsHttpBinding" contract="ITestService1">
	<identity>
	<dns value="localhost"/>
	</identity>
	</endpoint>
	<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
	</service>
</services>

Programatically:

  1. Create the metadata binding object using MetadataExchangeBinding class;
  2. Add an endpoint to the service host with the address, binding and contract.
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/Training/TestServices");

//Create ServiceHost
ServiceHost host = new ServiceHost(typeof(TestServices.TestService1), httpUrl);

//Add a service endpoint
host.AddServiceEndpoint(typeof(TestServices.ITestService1), new WSHttpBinding(), "");

//Adding metadata exchange endpoint
Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding ();
host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");

//Start the Service
host.Open();

Note: The mex endpoint is not browser friendly sent the WS-Transfer is a SOAP-based request.

Note: The mexHttpBinding is a standard binding that is equivalent to the wsHttpBinding with the security mode set to “None.

Enabling metadata expose through the service behavior
How to do it

The service behavior must have the HTTP GET flag active.
This flag defines whether the metadata will be accessible by an HTTP GET request.
If this attribute is set to true, then a default URL will be created for the metadata (usually the service’s address with the query string of ‘?wsdl’).

The url will lead to a WSDL file containing the description of the service operations, but without the description of the data contracts

The HTTP GET can be enabled either via the configuration file or programmatically.

Configuration file:

<system.serviceModel>
	<services>
		<service name="TestServices.TestService1" behaviorConfiguration="DefaultBehavior">
			<host>
				<baseAddresses>
					<add baseAddress="http://localhost:1234/Training/TestService1"/>
				</baseAddresses>
			</host>
			<endpoint address = "" binding = "wsHttpBinding" contract = "TestServices.ITestService"/>
		</service>
	</services>
	<behaviors>
		<serviceBehaviors>
			<behavior name="DefaultBehavior" >
				<serviceMetadata httpGetEnabled="true" />
			</behavior>
		</serviceBehaviors>
	</behaviors>
</system.serviceModel>

Programatically:

  1. Create the ServiceMetadataBehavior object and add to the service host description
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/Training/TestServices");

//Create ServiceHost
ServiceHost host = new ServiceHost(typeof(TestServices.TestService1), httpUrl);

//Add a service endpoint
host.AddServiceEndpoint(typeof(TestServices.ITestService1), new WSHttpBinding(), "");

//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);

//Start the Service
host.Open();
MEX vs WSDL

MEX and WSDL both outptut the same string – web service description document (WSDL), where

  • MEX generates the document by getting a single SOAP message over the specified transport protocol;
  • MEX exposes metadata over configurable endpoints and can use different types of transport protocols (e.g. HTTP, TCP, etc) and different types of security mechanisms;
  • WSDL may require several GET requests to get all the parts the document
  • WSDL can only use the HTP transport protocol