Probably the closest that I've seen is to use the JavaScriptSerializer
and pass in a JavaScriptTypeResolver
to the constructor. It doesn't produce JSON formatted exactly as you have it in your question, but it does have a _type
field that describes the type of the object that's being serialized. It can get a little ugly, but maybe it will do the trick for you.
Here's my sample code:
public abstract class ProductBase
{
public String Name { get; set; }
public String Color { get; set; }
}
public class Drink : ProductBase
{
}
public class Product : ProductBase
{
}
class Program
{
static void Main(string[] args)
{
List<ProductBase> products = new List<ProductBase>()
{
new Product() { Name="blah", Color="Red"},
new Product(){ Name="hoo", Color="Blue"},
new Product(){Name="rah", Color="Green"},
new Drink() {Name="Pepsi", Color="Brown"}
};
JavaScriptSerializer ser = new JavaScriptSerializer(new SimpleTypeResolver());
Console.WriteLine(ser.Serialize(products));
}
}
And the result looks like this:
[
{"__type":"TestJSON1.Product, TestJSON1, Version=1.0.0.0, Culture=neutral, Publ
icKeyToken=null","Name":"blah","Color":"Red"},
{"__type":"TestJSON1.Product, Test
JSON1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"hoo","Colo
r":"Blue"},
{"__type":"TestJSON1.Product, TestJSON1, Version=1.0.0.0, Culture=neu
tral, PublicKeyToken=null","Name":"rah","Color":"Green"},
{"__type":"TestJSON1.Dr
ink, TestJSON1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"P
epsi","Color":"Brown"}
]
I'm using the SimpleTypeConverter, which is part of the framework by default. You can create your own to shorten what's returned by __type
.
EDIT: If I create my own JavaScriptTypeResolver
to shorten the type name returned, I can produce something like this:
[
{"__type":"TestJSON1.Product","Name":"blah","Color":"Red"},
{"__type":"TestJSON1.Product","Name":"hoo","Color":"Blue"},
{"__type":"TestJSON1.Product","Name":"rah","Color":"Green"},
{"__type":"TestJSON1.Drink","Name":"Pepsi","Color":"Brown"}
]
Using this converter class:
public class MyTypeResolver : JavaScriptTypeResolver
{
public override Type ResolveType(string id)
{
return Type.GetType(id);
}
public override string ResolveTypeId(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
return type.FullName;
}
}
And just passing it into my JavaScriptSerializer
constructor (instead of the SimpleTypeConverter
).
I hope this helps!