Friday, August 11, 2006 8:21 PM
jsmith
The API that Weebles and Wobbles
It has been a while since I have blogged - my apologies. Life has been hectic.
One of the "not so fun" parts of writing a book on a beta technology like WCF is the constant movement of the API (not to mention changing the ship vehicle).
One change in the June CTP (appears to persist in the July CTP as well) that caught my attention is the change to the WS-MEX default behavior. In the old days (a few months ago) you could add an address to ServiceHost's constructor, and a WS-Mex endpoint would automagically appear. No mas. As of the June CTP, WS-Mex is off by default. There is quite a bit of documentation regarding how to enable WS-Mex in config files, but I could find none about how to do it imperatively. I think config files are great, but I like the ability to program too. After some time in the debugger and in reflector, it appears to be possible, but not pretty.
To configure a ServiceHost to open a WS-Mex endpoint in a simple WCF receiving app, do the following:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
// implement the IHelloWCF interface
sealed class Receiver : IHelloWCF {
static void Main(){
// define the base address to listen on
Uri baseAddress = new Uri("http://localhost:5000/HelloWCF");
// create the Binding
BasicHttpBinding binding = new BasicHttpBinding();
// new-up a ServiceHost type in a using statement
using(ServiceHost svc = new ServiceHost(typeof(Receiver), baseAddress)){
// use the contract, binding, and address to configure main endpoint
svc.AddServiceEndpoint(typeof(IHelloWCF), binding, String.Empty);
// add the Service Metadata behavior **NEW**
ServiceMetadataBehavior mexBehavior = new ServiceMetadataBehavior();
svc.Description.Behaviors.Add(mexBehavior);
// add the endpoint for metadata requests **NEW**
Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding();
svc.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
// begin listening on all endpoints
svc.Open();
Console.WriteLine("the receiver is ready");
Console.ReadLine();
}
}
// implement the method defined in the service contract
public void Say(String input){
Console.WriteLine("Message received, the body contains: {0}", input);
}
}
// define the service contract
[ServiceContract]
interface IHelloWCF {
[OperationContract]
void Say(String input);
}
The new stuff has **NEW** in the comments. Basically, you now have to add a Mex endpoint manually. There are a few catches though. First, you have to call the MetadataExchangeBindings.CreateMexHttpBinding method to get the correct mex binding. It is worth noting that this is the only binding that defines factory methods. Also, you have to add the ServiceMetadataBehavior to the description BEFORE you add the mex endpoint.