[System.ServiceModel] Don't try to deserialize `void` messages.
authorJonathan Pryor <jonpryor@vt.edu>
Fri, 20 Jan 2012 05:04:10 +0000 (00:04 -0500)
committerJonathan Pryor <jonpryor@vt.edu>
Fri, 20 Jan 2012 05:18:54 +0000 (00:18 -0500)
commit00e29089c72bbeff3270f53e2098b7bf4c5dc1ef
treecba2fc6b8bc580994948c427261850e9ae3ff8eb
parent5a6f9b7e521fcba3e9ed9f2b4032805503be84bb
[System.ServiceModel] Don't try to deserialize `void` messages.

Fixes: http://bugzilla.xamarin.com/show_bug.cgi?id=1164

The breakage reported in #1164 was caused by commit 106fdeb4, which
fixed bxc206. The problem is that in fixing bxc206, response messages
of a type having a MessageContractAttribute custom attribute were
changed to have a `void` return type, according to the
MessageDescription's Body.ReturnValue.Type property.

This fix is correct, in that it's what .NET does, but it broke XML
deserialization which expected the "actual" return type to exist, not
`void`.

Case in point: the added IService1.EndJSMGetDatabases() method will
have a MessageDescription with a Body.ReturnValue.Type=typeof(void).
The problem is that deserializing this message will fail:

System.Runtime.Serialization.SerializationException: Deserializing
type 'System.Void'. Expecting state 'EndElement'. Encountered state
'Text' with name '' with namespace ''.

Obviously this is not good. ;-)

The fix is simple: don't use the MessageDescription's ReturnValue if
it's `typeof(void)`.

There are two added wrinkles:

 1. Writing a test case for the above.

 2. The test case broke with another error: a NRE within
    BaseMessagesFormatter.MessageObjectToParts(). This is because
    when ContractDescriptionGenerator.GetMessage() sets the
    ReturnValue for a response message, it doesn't set
    MessagePartDescription.MemberInfo.
    BaseMessagesFormatter.MessageObjectToParts(), meanwhile, was
    checking the ReturnValue's MemberInfo...which was null.

    Add a null check here so that the actual bug can be tested.
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug652331_2Test.cs