How to: Publish Metadata for a Service Using Code
This is one of two How To topics that discusses publishing metadata for a Windows Communication Foundation (WCF) service. There are two ways to specify 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: |
---|
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 fashion 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.
Imports System
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
<ServiceContract()> _
Public Interface ISimpleService
<OperationContract()> _
Function SimpleMethod(ByVal msg As String) As String
End Interface
Class SimpleService
Implements ISimpleService
Public Function SimpleMethod(ByVal msg As String) As String Implements ISimpleService.SimpleMethod
Console.WriteLine("The caller passed in " + msg)
Return "Hello " + msg
End Function
End Class
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
Within the main method of a console application, instantiate a ServiceHost object by passing in the service type and the base address.
Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("https://localhost:8001/MetadataSample"))
ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("https://localhost:8001/MetadataSample"));
Create a try block immediately below the code for step 1, this catches any exceptions that get thrown while the service is running.
Try
try {
Catch commProblem As CommunicationException Console.WriteLine("There was a communication problem. " + commProblem.Message) Console.Read() End Try
} catch (CommunicationException commProblem) { Console.WriteLine("There was a communication problem. " + commProblem.Message); Console.Read(); }
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 Dim smb As ServiceMetadataBehavior = svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)() 'If not, add one If (smb Is Nothing) Then smb = New ServiceMetadataBehavior() End If
// 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();
Set the HttpGetEnabled property to true.
smb.HttpGetEnabled = True
smb.HttpGetEnabled = true;
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
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
Add the ServiceMetadataBehavior instance to the service host's behaviors collection.
svcHost.Description.Behaviors.Add(smb)
svcHost.Description.Behaviors.Add(smb);
Add the metadata exchange endpoint to the service host.
'Add MEX endpoint svcHost.AddServiceEndpoint( _ ServiceMetadataBehavior.MexContractName, _ MetadataExchangeBindings.CreateMexHttpBinding(), _ "mex")
// Add MEX endpoint svcHost.AddServiceEndpoint( ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex" );
Add an application endpoint to the service host.
'Add application endpoint svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
// Add application endpoint svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
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()
// 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();
Build and run the console application.
Use Internet Explorer to browse to the base address of the service (https://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."
Example
The following code example shows the implementation of a basic WCF service that publishes metadata for the service in code.
Imports System
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
<ServiceContract()> _
Public Interface ISimpleService
<OperationContract()> _
Function SimpleMethod(ByVal msg As String) As String
End Interface
Class SimpleService
Implements ISimpleService
Public Function SimpleMethod(ByVal msg As String) As String Implements ISimpleService.SimpleMethod
Console.WriteLine("The caller passed in " + msg)
Return "Hello " + msg
End Function
End Class
Module Module1
Sub Main()
Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("https://localhost:8001/MetadataSample"))
Try
'Check to see if the service host already has a ServiceMetadataBehavior
Dim smb As ServiceMetadataBehavior = svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)()
'If not, add one
If (smb Is Nothing) Then
smb = New ServiceMetadataBehavior()
End If
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(GetType(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 commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " + commProblem.Message)
Console.Read()
End Try
End Sub
End Module
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("https://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();
}
}
}
}
See Also
Tasks
How to: Host a WCF Service in a Managed Application
How to: Publish Metadata for a Service Using a Configuration File
Concepts
Metadata Architecture Overview
Using Metadata
Other Resources
© 2007 Microsoft Corporation. All rights reserved.
Build Date: 2009-08-07