IRequestChannel and One-Way Contracts

I’ve been working this week on implementing some custom WCF transport channels. The one I was working on initially is a two-way send channel, so, naturally, I decided to begin by having my channel implement the IRequestChannel shape.

This was working fine until I decided to try a one-way operation on top of my two-way channel, which was interesting because I was not implementing an equivalent part of the transport supporting IOutputChannel.

I was expecting it to fail right from the start, but, surprisingly enough, it almost worked. That is, the transport channel was called, executed, and only bombed when the WCF stack ran into the unexpected response message. The error message I was seeing was something like this:

System.ServiceModel.ProtocolException: The one-way operation returned a non-null message with Action=''.

Looking around, I realized a couple of things: First of all, the built-in HTTP transports in WCF also implement only IRequestChannel, and yet, somehow, they still manage to work just fine in this case.

The second thing that came to mind was that I was using a custom MessageEncoder. Granted, it was a very rough and crappy encoder, but it was mostly enough for me to test a few things about my custom transport.

That last part sparked something deep in my memory: I seemed to vaguely remember something about encoders that might be related, so I turned right away to the best source for everything WCF related: Nicholas Allen’s blog.

Fortunately, Dr. Nick did not disappoint! In one of his articles about writing a custom POX Message Encoder, he included this little gem:

“One of the properties of the standard message encoders is that they only surface up messages that have a non-empty message body.”

That was indeed what I was seeing: My custom transport was indeed returning a message from IRequestChannel.Request(), but it had no content at all (something particular to the kind of request I was making over the one-way channel).

Once I changed my custom encoder to ignore the empty message, it worked just fine.

Comments (2)

larswFebruary 5th, 2009 at 7:23 am

Hi Thomas,
Love your work – keep it up!
I’ve been planning a XMPP ("Jabber") Transport Channel with support for XEP-0072; SOAP over XMPP for some time (or, the idea dawned on me some time ago, and I’m about to pick it up again).
Do you have any advice (in general) where to look for good resources on custom transport channels? I’ve read Dr. Nick’s blog posts – but do you know of any good sample implementations?
Coming to think of it, I know that the ActiveMQ project have a WCF channel, so I better check it out.
–larsw

tomasrFebruary 6th, 2009 at 4:46 am

@Lars: I’ve posted a few links in the past with wcf channel resources, like this: http://winterdom.com/weblog/2007/02/14/WritingAWCFTransportChannelPart1.aspx
Some of the links there, are, unfortunately, dead now. Also, here’s another good WCF channel sample: http://weblogs.shockbyte.com.ar/rodolfof/archive/2007/07/15/wcf-mail-transport-channel.aspx

Leave a comment

Your comment