I\'m trying to serialize a class hierarchy to a Json string using DataContractJsonSerializer
, in a WCF service.
the default behaviour for serializing a derived clas
This page describes the circumstances under which the __type property is emitted. In short, in WCF, if you use a derived type, and a KnownTypeAttribute, then you're going to get a __type property.
Example:
Assume
[DataContract]
[KnownType(typeof(Subscriber))]
public class Person { ... }
[DataContract]
public class Subscriber : Person { ... }
This code generates a __type property:
var o = new Subscriber("Fleming");
var serializer = new DataContractJsonSerializer(typeof(Person));
serializer.WriteObject(Console.OpenStandardOutput(), o);
But this code does not:
var o = new Subscriber("Fleming");
var serializer = new DataContractJsonSerializer(typeof(Subscriber));
serializer.WriteObject(Console.OpenStandardOutput(), o);
Notice that the second snip uses a DCJS with the same type as the object being serialized.
To avoid the __type, don't use derived types, or to be precise, use a serializer typed to the type you are actually serializing. If the serialization is being performed implicitly by a WCF method, then the method must be typed appropriately. In my example, it means you must use a return type of "Subscriber", and not the parent type, "Person".
The __type is emitted into the JSON stream by the (private) WriteServerTypeAttribute method on the (internal) System.Runtime.Serialization.Json.XmlJsonWriter class. There is no public, documented, supported way to modify that, as far as I can tell.
To avoid this, you'd maybe need to return a string from the WCF method, perform the serialization yourself, and post-process the emitted JSON.
If you don't mind the __type thing, but just want to remove the qualifying namespace from the value, then put your types in the global namespace. In other words, put them outside of any namespace
declaration in code.
Example: When the data types reside in a namespace, and when I used a derived type, the serialized JSON looks like this:
{
"__type":"Subscriber:#My.Custom.Namespace",
"Index":604455,
"Name":"Fleming",
"Id":580540
}
When the data types reside in the global namespace, it looks like this:
{
"__type":"Subscriber:#",
"Index":708759,
"Name":"Fleming",
"Id":675323
}