2

I have a WCF service with the following custom binding:

    <binding name="binaryHttpBinding" >
      <binaryMessageEncoding />
      <httpTransport maxReceivedMessageSize="2147483647" />
    </binding>

(The client has of course configuration that matches this binding). The problem is that client doesn't receive generic FaultException, e.g. "T" is not received by the client, I can verify it if I trace the calls. However if I replace binaryMessageEncoding with textMessageEncoding using Soap 1.2, all fault exceptions come enriched with fault detail.

I searched on the net and wasn't able to find any information that would claim that binary message encoding over HTTP is not compatible with generic WCF fault exceptions. Also it doesn't look like I can control much of the binary message encoding - for example I can't set in the configuration SOAP message version (not supported by WCF for binary encoding). I wonder whether this scenario is supported.

Vagif Abilov
  • 9,835
  • 8
  • 55
  • 100

1 Answers1

3

After spending quite some hours on trying to figure out what could go wrong, I've finally made it work. Two reasons for failure, none of them obvious.

  1. The fault message class has overridden ToString method that did some computation. Sure it was unwise to put such logic in ToString, but who could guess this would affect just binary serialization?
  2. FaultException constructor has an optional parameter "actionName" that I set to the name of the method where the exception occurred. Apparently WCF is quite picky about what can be assigned to action name but leaving it blank always works. Again, who could guess that it only affect binary serialization and in such strange way (so it discards the message fault on the client side)?
Vagif Abilov
  • 9,835
  • 8
  • 55
  • 100
  • I have the same problem, but I'm not sure how to get your solution working. For 2 I am not passing an `actionName` already, so I think that's ok. But what did you change for 1? My fault class doesn't have a `ToString` method, if that's what you were meaning. – Adam Goodwin Dec 21 '17 at 13:23
  • Alright, I found my issue as well. Our service contract had an attribute on it that implemented `IErrorHandler`, and it was in the `ProvideFault` implementation where we were setting the action similar to what you were doing (your second point). Leaving the action parameter of `System.ServiceModel.Channels.Message.CreateMessage(...)` null, or keeping it as the existing action value, solved the problem for me. – Adam Goodwin Dec 22 '17 at 12:11
  • A good explanation of the issue is here: https://blogs.msdn.microsoft.com/drnick/2007/02/05/actions-for-faultexceptions/ The gist is that the expected action value is by default based on the FaultContract and its type. "For instance, if my service contract is IService, my operation is called Action, and I'm using a typed FaultException instance, then the default fault action is http://tempuri.org/IService/ActionStringFault." – Adam Goodwin Dec 22 '17 at 12:21