I have a WCF REST service that accepts a custom DataContract argument as JSON which may either by the super-type or a sub-type. When I pass JSON containing extra whitespace, the object always deserializes as the super-type. When I strip all whitespace from the JSON, the object deserializaes as the sub-type.
Here is an example:
[DataContract]
[KnownType(typeof(SubClass))]
public class SuperClass
{
[DataMember]
public string Message { get; set; }
}
[DataContract]
public class SubClass : SuperClass
{
[DataMember]
public string Extra { get; set; }
}
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke]
void LogMessage(SuperClass arg);
}
public class Service1 : IService1
{
public void LogMessage(SuperClass arg)
{
if (arg is SubClass)
{
Debug.WriteLine("SubClass");
}
else if (arg is SuperClass)
{
Debug.WriteLine("SuperClass");
}
}
}
If I send the following message, the service will print SuperClass
:
POST http://localhost:5763/Service1.svc/LogMessage HTTP/1.1
User-Agent: Fiddler
Content-Type: text/json
Host: localhost:5763
Content-Length: 86
{ "__type":"SubClass:#WhitespaceTest", "Message":"Message", "Extra":"Extra" }
I get the same result if I "pretty print" the packet as well so that the JSOn is split over multiple lines. However, the service will print SubClass
if I strip the whitespace as follows:
POST http://localhost:5763/Service1.svc/LogMessage HTTP/1.1
User-Agent: Fiddler
Content-Type: text/json
Host: localhost:5763
Content-Length: 73
{"__type":"SubClass:#WhitespaceTest","Message":"Message","Extra":"Extra"}
I've debugged the output of System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.ToString()
and noticed that the XML generated from the JSON is different between the 2 packets:
<!-- First packet, deserializes to SuperClass -->
<root type="object">
<__type type="string">SubClass:#WhitespaceTest</__type>
<Message type="string">Message</Message>
<Extra type="string">Extra</Extra>
</root>
<!-- Second packet, deserializes to SubClass -->
<root type="object" __type="SubClass:#WhitespaceTest">
<Message type="string">Message</Message>
<Extra type="string">Extra</Extra>
</root>
So, it seems as though the whitespace confuses the JSON deserializer. Does anyone know why this happens and what I can do about it?