Возможно, самое близкое, что я видел, - это использование JavaScriptSerializer
и передача JavaScriptTypeResolver
в конструктор. Он не производит JSON, отформатированный так, как у вас есть в вашем вопросе, но у него есть поле _type
, которое описывает тип сериализуемого объекта. Это может стать немного уродливым, но, возможно, это поможет вам.
Вот мой пример кода:
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));
}
}
И результат выглядит так:
[
{"__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"}
]
Я использую SimpleTypeConverter, который является частью фреймворка по умолчанию. Вы можете создать свой собственный, чтобы сократить то, что возвращается на __type
.
РЕДАКТИРОВАТЬ : Если я создам свой собственный JavaScriptTypeResolver
, чтобы сократить возвращаемое имя типа, я могу создать что-то вроде этого:
[
{"__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"}
]
Используя этот класс конвертера:
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;
}
}
И просто передать его в мой JavaScriptSerializer
конструктор (вместо SimpleTypeConverter
).
Надеюсь, это поможет!