Using One-Way Operations with the WCF Adapter in BizTalk


If you’ve used the WCF Adapter in BizTalk to communicate using one-way contracts with WCF Clients (by having a WCF Receive Location) or WCF Services (by having a WCF Send Port), you must have realized that the WCF Adapter cannot handle one-way contracts easily.

The current design of the adapter is this:

  • For send ports, if the binding used supports any one of IRequestChannel, IRequestSessionChannel or IDuplexChannel, then we attempt to use the IRequestChannel contract. As a result all operations now have to return a valid response, effectively requiring all operations to be two-way.
  • For receive locations, if the binding used supports any one of IReplyChannel, IReplySessionChannel or IDuplexChannel, then we attempt to create a service host configured with a two-way contract. As a result, we return a non-null response message to the WCF Client for every incoming message.

If your contract is one-way (i.e., all operations are one-way operations), then you have a workaround. You could write a custom binding element which only supports one-way channels. You could then use the customBinding binding and add each binding element you require, making sure that your custom binding element (which only supports 1-way channels) is present in the stack. Therefore, when the WCF Adapter tries to determine whether your binding supports two-way channels, it will get a negative reply.

But what if your contract contains both one-way and two-way operations?

For send ports, you can do this: add an endpoint behavior which inserts a custom binding element in the binding stack. If the response message for any outgoing request is null (which would imply that the operation you invoked was a one-way operation), then your custom IRequestChannel channel (part of your custom binding element) can create a dummy message and return it. This will keep the IRequestChannel contract happy, and the WCF Adapter won’t complain. Of course, the assumption is that you are using a One Way Send Port.

For receive locations, you can do this: add an endpoint behavior which exposes a property/properties via which you can specify the actions which correspond to one-way operations. Your endpoint behavior can also add a dispatch message inspector. The inspector, on seeing a response go out for a message which was supposed to be one-way, can replace that response with a null message. Of course, the assumption here is that you are using a One Way Receive Location.

NOTE: in order to use any of the workarounds above you need to use the WCF-Custom adapter, since that is the only adapter which allows you to add behaviors or configure the customBinding binding with user-specified binding elements.

The code for the two behaviors mentioned above can be downloaded from http://biztalkserverteam.codeplex.com/releases/view/58746#DownloadId=195099


Comments (3)

  1. Matt Milner says:

    Can someone explain why this is the behavior?  Was there a good reason for changing the semantics of what a one-way operation is in WCF/Web Services?  If I want a one-way port, I want a one-way service operation – or at least I might.  Give me a check box to enable that – don’t make me write a behavior.  And where is that response message coming from?  if from the adapter, then again, let me tell you not to send it. If I’m using a client like Infopath – I have to tell it to do a one-way operation, but it fails as data is returned when it doesn’t expect it to be.  Sorry to vent, but this is frustrating behavior and I haven’t heard a good use case for why it is this way.  

  2. anilpr@microsoft.com says:

    In WCF, there is no way to detect if one-way operation finished properly on destination service. Only when operations are marked two way, the client can be sure of end-result of operation. Since BizTalk is all about reliable message processing, it can’t afford this unreliable behavior (on send side). So I guess BizTalk WCF-Adapter picked this default two-way contract behavior for one-way operations.

  3. Hi Mustansir, Can you please share the steps to use these behaviors, because I am not very much familiar with using WCF-Custom adapter and I need to consume the WCF service having one-way operation in one of the project.