您可以添加一个自定义JsonConverter
,Dictionary<string,Position>
将字典值序列化为列表。转换器假定可以在反序列化期间以某种方式从字典值中提取字典键。
首先,定义以下转换器:
public class PositionDictionaryConverter : DictionaryAsValueListConverter<Position>
{
protected override string GetKey(Position position) { return position.Ticker; }
}
public abstract class DictionaryAsValueListConverter<TValue> : JsonConverter
{
protected abstract string GetKey(TValue value);
public override bool CanConvert(Type objectType)
{
return typeof(Dictionary<string, TValue>).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.MoveToContent().TokenType == JsonToken.Null)
return null;
var list = serializer.Deserialize<List<TValue>>(reader);
var dictionary = (IDictionary<string, TValue>)(existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator());
foreach (var item in list)
dictionary.Add(GetKey(item), item);
return dictionary;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((IDictionary<string, TValue>)value).Values);
}
}
public static partial class JsonExtensions
{
public static JsonReader MoveToContent(this JsonReader reader)
{
if (reader.TokenType == JsonToken.None)
reader.Read();
while (reader.TokenType == JsonToken.Comment && reader.Read())
;
return reader;
}
}
然后将其应用于您的模型,如下所示:
public class Portfolio
{
public string Name {get; set;}
[JsonConverter(typeof(PositionDictionaryConverter))]
public Dictionary<string,Position> Positions {get; set;}
}
或者,在设置中使用它,如下所示:
var settings = new JsonSerializerSettings
{
Converters = { new PositionDictionaryConverter() },
};
var json = JsonConvert.SerializeObject(root, settings);
当然,转换器假定字典键和股票名称是相同的。
演示小提琴在这里。