我有一个类,FooCollection
,它实现了IEnumerable<Foo>
,还提供了一个索引器,通过它可以通过名称查找Foo
。在功能上它只是字典的只读。但它并不是真正的字典,因为用户无法确定密钥。
无论如何,我希望JSON.NET将此对象序列化为JSON字典,而不是现在正在执行的数组。坚持JsonDictionaryAttribute
不起作用:然后它什么都不做。
线索?
答案 0 :(得分:10)
您可能需要为FooCollection
课程创建自定义JsonConverter
,以便按照您希望的方式对其进行序列化。由于你还没有发布任何代码,我只是为了举例说明。假设您的Foo
和FooCollection
类看起来像这样:
class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
class FooCollection : IEnumerable<Foo>
{
private List<Foo> list = new List<Foo>();
public void Add(Foo foo)
{
list.Add(foo);
}
public Foo this[string name]
{
get { return list.Find(f => f.Name == name); }
}
public IEnumerator<Foo> GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)list).GetEnumerator();
}
}
以下转换器会将FooCollection
序列化,就像它是字典一样。我假设您希望转换器使用Name
属性的值作为每个Foo
的键,以便进行序列化(以匹配集合上的索引器),这就是如何我实现了它。您可以通过修改GetFooKey()
方法将其更改为其他内容。
class FooCollectionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(FooCollection));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteStartObject();
foreach (Foo foo in (FooCollection)value)
{
writer.WritePropertyName(GetFooKey(foo));
serializer.Serialize(writer, foo);
}
writer.WriteEndObject();
}
// Given a Foo, return its unique key to be used during serialization
private string GetFooKey(Foo foo)
{
return foo.Name;
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
以下是演示如何使用转换器的示例程序。
class Program
{
static void Main(string[] args)
{
FooCollection coll = new FooCollection();
coll.Add(new Foo { Id = 1, Name = "Moe" });
coll.Add(new Foo { Id = 2, Name = "Larry" });
coll.Add(new Foo { Id = 3, Name = "Curly" });
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new FooCollectionConverter());
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
string json = JsonConvert.SerializeObject(coll, settings);
Console.WriteLine(json);
}
}
这是上述程序的输出:
{
"Moe": {
"Id": 1,
"Name": "Moe"
},
"Larry": {
"Id": 2,
"Name": "Larry"
},
"Curly": {
"Id": 3,
"Name": "Curly"
}
}