I have created the following classes. one base class IObject and 2 derived classes A and B.
[KnownType(typeof(B))]
[KnownType(typeof(A))]
[DataContract(Name = "IObject")]
public class IObject
{
}
[DataContract(Name="A")]
public class A : IObject
{
[DataMember]
public string s1 { get; set; } // Tag Name as it will be presented to the user
}
[DataContract(Name="B")]
public class B : IObject
{
[DataMember]
public string s2 { get; set; }
}
I have also created the following Service:
[ServiceKnownType(typeof(B))]
[ServiceKnownType(typeof(A))]
public void GetR(IObject obj)
{
B other = (B)obj;
}
What i want to do is get an instance of A or B but i don't know which one i will get so i expect to get an IObject and cast it later to either A or B as shown in the example i put.
What happens when i send a json string containing s2 string is that i get IObject instance and not B instance. What is wrong with the code?
Example of the client i'm using :
var url = serviceURL;
var data = {s2: "Data"};
var json = JSON.stringify(data);
$.ajax({
type: "POST",
url: url,
data: data,
contentType: "application/json",
dataType: 'json'
});
Edited: I have uploaded an example code to gitHub at the following link: https://github.com/AlgoEitan/27588144
The client there is a c# client (I've tried it with both c# and javascript - web browser client)
DataContractJsonSerializer
has a specific format in which it stores hints about known type information for polymorphic types, which one can discover with a bit of testing. I copied and pasted your classes as-is, and created the following test code:With that, the following JSON was created:
Where
Tile.DataContractJsonSerializerPolymorphism
happens to be the name of the CLR namespace in my test application. So, as you can see, the known type information got tucked away in this extra JSON property__type
. Now, if you were usingDataContractJsonSerializerHelper
in your client also, you would never know this, because communication would just work. But you are usingJSON.stringify()
which does not have this logic. So, you may have to manually add the"__type":"DataContractName:DataContractNamespace"
property on the client side.More about the format for polymorphic types can be found here. (I only tracked this documentation down after finding the hidden
__type
parameter, which gave me an extra Google search term.)FYI, here is the helper class I used with the test code: