Web Services have to expose metadata so that clients can understand how to interact with and make use of that service endpoint.This metadata is generally exchanged in the form Web Services Description Language(WSDL) and XSD schemas describing the bindings,network addresses,messages to be exchanged & also operations and data types.WCF provides a very rich infrastructure and set of APIs to export,publish,retrieve and import service metadata.In this series of posts we will try to examine the important classes involved in this process and the extension hooks.
The WCF classes representing this metadata is as shown below:
The metadata of a service is represented the class System.ServiceModel.Description.MetdataSet which contains references to the schemas, policies,wsdl documents as a collection of System.ServiceModel.Description.MetdataSection objects.MetadataSection exposes the property MetaData (of Object type) which contains the WSDL,Policies,etc.
Exporting MetaData
The process of exporting the metadata involves converting the information related to service endpoint into understandable format like WSDL.For this abstract base class System.ServiceModel.Description.MetadataExporter is available.Presently there is one implementation available that is System.ServiceModel.Description.WsdlExporter which exports the metadata in WSDL format.The MetadataExporter class has an internal constructor hence cannot be overridden and used by custom classes.
To add any extension to the metadata export process we need to write a custom class implementing the System.ServiceModel.Description.IWsdlExportExtension interface.This class needs to be added to the WCF service infrastructure as a Service,Contract,Operation or Endpoint behavior.
The class shown below accepts a comment string as constructor parameter and adds that comment string as a documentation of the WSDL porttype element.
public class CommentExporter : Attribute,IWsdlExportExtension, IContractBehavior
{
string comment;
public CommentExporter(string comment)
{
this.comment = comment;
}
#region IWsdlExportExtension Members
void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
XmlElement elem = null;
XmlDocument xdoc = null;
context.WsdlPortType.Documentation = string.Empty;
if (context.Contract != null)
{
if (context.WsdlPortType.DocumentationElement != null)
{
elem = context.WsdlPortType.
DocumentationElement.OwnerDocument.
CreateElement("wsdlportcomment");
elem.InnerText = comment;
context.WsdlPortType.DocumentationElement.AppendChild(elem);
}
}
}
void IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
return;
}
#endregion
#region IContractBehavior Members
void IContractBehavior.AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
return;
}
void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
return;
}
void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
return;
}
void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
return;
}
#endregion
}
It also implements the IContractBehavior interface and Attribute class so that it can be applied as a contract behavior on the service contract as shown below:
[ServiceContract]
[CommentExporter("Test Comment")]
interface ITest
{
[OperationContract]
int Add(int i,int j);
}
Now the next step is to publish this metadata.
Publishing MetaData
This the process of making metadata available to client over standard protocols.There are two ways of doing it.
We can expose metadata exchange endpoints compliant to WS-MetaDataExchange standards.To do this we have to use the IMetadataExchange service contract and 4 default MetadataExchange bindings e.g. mexHttpBinding,mexHttpsBinding,mexTcpBinding,mexNamedPipeBinding.A sample end point configuration is shown below:
<endpoint address=”http://localhost:7018/Test/mex” binding=”mexHttpBinding”
bindingConfiguration=”" name=”mex” contract=”IMetadataExchange
<endpoint address="http://localhost:7018/Test/mex" binding="mexHttpBinding"
bindingConfiguration="" name="mex" contract="IMetadataExchange">
Metadata can also be published using the ServiceMetadataBehavior class as shown below:
using(ServiceHost host = new ServiceHost(typeof(TestService)))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:7018/Test/WSDL");
host.Description.Behaviors.Add(smb);
host.Open();
Console.Read();
}
This means the WSDL description will be available over Http with a GET request using URL http://localhost:7018/Test/WSDL. The same can done using config as well.
On typing http://localhost:7018/Test/WSDL in the browser the WSDL will be displayed as shown below:
In the next post we will discuss about retrieving & importing of metadata in details.


WCF & MetaData Exchange – Part 1 « Sankarsan’s Journal…
Thank you for submitting this cool story – Trackback from DotNetShoutout…
WCF & MetaData Exchange – Part 1 « Sankarsan’s Journal…
Thank you for submitting this cool story – Trackback from Servefault.com…
WCF & MetaData Exchange – Part 1 « Sankarsan’s Journal…
Thank you for submitting this cool story – Trackback from PimpThisBlog.com…
[...] This post was mentioned on Twitter by techno@solidsoft, Sankarsan Bose. Sankarsan Bose said: Completed the post..WCF & MetaData Exchange – Part 1…http://bit.ly/9Nmd7b [...]
[...] WCF & MetaData Exchange – Part 1 « Sankarsan’s Journal [...]
[...] WCF & MetaData Exchange – Part 1 « Sankarsan’s Journal [...]
Hello Sankarsan,
I liked your article but i have one query regarding Metadata exchange using endpoints.
while we are exchanging metadata using HTTP-GET(by using ).We can see the WSDL file on http path.But if we exposed metadata using tcp metadataexchange endpoint.How can we see the WSDL file? I tried with TCP address but not available there.
Please help to understand this.
Thanks in Advance