This question came up in a recent consulting gig – so I thought I summarize the options and provide some links.
The easiest way to expose metadata is to provide a base address and enable metadata publishing in the serviceMetadata behavior. You enable publishing by setting the http(s)GetEnabled attribute to true. When it comes to security, your options are limited. You won’t get any authentication this way – but you can enforce SSL. You can also specify the publishing URL which might solve the security problem at an infrastructure level.
This option only allows to retrieve metadata via HTTP.
A more general pupose approach is to expose a Metadata Exchange (MEX) endpoint. This endpoint has to implement the (pre-defined) IMetadataExchange interface and is typically used with a mex* binding (for HTTP(S), TCP and NamedPipes) e.g.
There are also situations where MEX endpoints are required, e.g. WCF needs them to query policy when issued tokens and STSes are used.
The mex* bindings don’t support security but you can expose metadata over arbitrary bindings as long as you use the IMetadataExchange contract. This gives you the full WCF security feature set.
The only problem is that svcutil.exe will not work out of the box with other bindings besides mex*. To make this work you would have to modify the svcutil.exe.config file in the framework directory. If you want to programmatically retrieve the metadata you have to configure the client channel accordingly.
If you want to secure a MEX endpoint, either use a secure binding or put the endpoint on some uri/port that is not generally reachable.
Metadata via WMI
Another way to retrieve metadata from a WCF service is via WMI. This is totally indepent from the base address, the serviceMetadata behavior or any MEX endpoints. By ACLing the WMI namespace in the computer management MMC snap-in you can control who has access to the WMI objects.
To enable WMI publishing you have to add this fragment to your serviceModel config:
<diagnostics wmiProviderEnabled=“true” />
To retrieve the metadata, this code snippet should get you started:
private static void DumpAllMetadata()
ManagementClass mc =
ManagementObjectCollection mos = mc.GetInstances();
foreach (ManagementObject mo in mos)
Console.WriteLine(“n”+ mo[“Name”] + “n”);
foreach (string s in (string)mo[“Metadata”])