Probablemente lo más cercano que he visto es usar el JavaScriptSerializer
y pasar un JavaScriptTypeResolver
al constructor. No produce formato JSON exactamente como lo tiene en su pregunta, pero tiene un campo _type
que describe el tipo de objeto que se está serializando. Puede ponerse un poco feo, pero tal vez te sirva de algo.
Aquí está mi código de ejemplo:
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));
}
}
Y el resultado es idéntico:
[
{"__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"}
]
estoy usando el SimpleTypeConverter, que es parte del marco por defecto. Puede crear el suyo propio para acortar lo que devuelve __type
.
EDITAR: Si creo mi propia JavaScriptTypeResolver
para acortar el nombre del tipo devuelto, puedo producir algo como esto:
[
{"__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"}
]
El uso de esta clase convertidor:
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;
}
}
Y de paso en mi JavaScriptSerializer
constructor (en lugar de SimpleTypeConverter
).
Espero que esto ayude!
Oye, ¿a encontrar una solución para esto actualmente estoy enfrentando un problema similar? Un servidor (Java, Glassfish con Jersey) serializa objetos a JSON y el cliente (C#) necesita deserializar esto. Cuando se usa XML todo funciona bien ... – hage