After my previous post on how to use a Channel Factory in Silverlight, I received quite a few questions through Twitter, the main one being: “how do you pass in parameters to an operation?” Next to that, someone also suggested to use a custom binding with binary encoding instead of the default basicHttpBinding. So I decided to write a post explaining how to achieve those two things – welcome to part 2: binary cows & new-born calves! 🙂
First up: passing in parameters to the operation. To keep in theme with the last solution, we’re going to allow the user to create a new-born calve on the client, and send that to the server. For the sake of the demo, the only thing we’ll do on the server is fill out the correct ImageUri, and we’ll send the resulting Cow object back to the client.
public Domain.Cow AddCow(Domain.Cow newBorn) { newBorn.ImageUri = new Uri(http://localhost:5873/calve_clipart.png,
UriKind.Absolute);
return newBorn;
}
The part that confused some people was how to write the correct async signature to match the regular operation contract. It’s actually quite simple: in the Begin method, you should add the parameter(s) you want to pass in before the IAsyncResult and state parameters:
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginAddCow(Cow newBorn, AsyncCallback callback, Object state);
Cow EndAddCow(IAsyncResult result);
To call this method, you should write code like this:
private void AddCowExecution() { Cow newBorn = new Cow() { Name = "New born" }; // call CowService WCF service ICowService channel = GetCowServiceFactoryChannel(); var y = channel.BeginAddCow(newBorn, (asyncResult) => { // add Cow var returnVal = channel.EndAddCow(asyncResult); Deployment.Current.Dispatcher.BeginInvoke(() => { // add to collection Cows.Add(returnVal); }); } , null); }
Now, how do you make sure you use binary encoded messages through a custom binding? Two things should be done for this: when creating the Channel Factory on the client, you should create your custom binding and pass that in. On the server, you need an endpoint that uses the same kind of custom binding. That means you have to change two things: first, the client-side code: we create a custom binding and add the necessary binding elements (binary encoding over http transport):
CustomBinding customBinding = new CustomBinding(); customBinding.Elements.Add(new BinaryMessageEncodingBindingElement()); customBinding.Elements.Add(new HttpTransportBindingElement()); EndpointAddress endpointAddress = new EndpointAddress(CowServiceEndpointAddress); CowServiceChannelFactory = new ChannelFactory<ICowService>
(customBinding, endpointAddress);
… and then the web.config to make sure it has a correct endpoint: define the custom binding, and add the binding & binding configuration elements to your endpoint:
<bindings> <customBinding> <binding name="ChannelFactoryWithCows.CustomBinaryBinding"> <binaryMessageEncoding /> <httpTransport /> </binding> </customBinding> </bindings>
and:
<service name="ChannelFactoryWithCows.Web.CowService"> <endpoint address="" binding="customBinding" bindingConfiguration="ChannelFactoryWithCows.CustomBinaryBinding" contract="ChannelFactoryWithCows.Contracts.ICowService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service>
So there we go – we now have a cow farm, compressing the cows before travel and allowing new calves to be born 🙂 You can download the source code here.