如何将对象模型持久化为JSON并序列化字典为其值数组? [英] How to persist an object-model to JSON and serialize a dictionary as its array of values?

查看:84
本文介绍了如何将对象模型持久化为JSON并序列化字典为其值数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public class Portfolio
{
    public string Name {get; set;}
    public Dictionary<string,Position> Positions {get; set;}
}

public class Position
{
    public string Ticker {get; set;}
    public decimal Size {get; set;}
}

JsonConvert.SerializeObject(portfolio);

将产生例如:

{
  "Name": "SP500",
  "Positions": {
        "AOS": {
          "Ticker": "AOS",
          "Size": 100,
        },
        "ABT": {
          "Ticker": "ABT",
          "Size": 100,
        }
    }
}

但是我想最小化空间并将位置存储为数组:

But I'd like to minimize space and store the positions as an array :

{
  "Name": "SP500",
  "Positions": 
  [
      {
        "Ticker": "AOS",
        "Size": 100,
      },
      {
        "Ticker": "ABT",
        "Size": 100,
      }
  ]
}

如何将json保存并加载到我的对象模型中?

How to save and load this json into my object model ?

推荐答案

您可以添加

You could add a custom JsonConverter for Dictionary<string,Position> that serializes the dictionary values as a list. The converter assumes that the dictionary key can be extracted somehow from the dictionary value during deserialization.

首先,定义以下转换器:

First, define the following converter:

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;
    }
}

然后按如下所示将其应用于您的模型:

Then apply it to your model as follows:

public class Portfolio
{
    public string Name {get; set;}

    [JsonConverter(typeof(PositionDictionaryConverter))]
    public Dictionary<string,Position> Positions {get; set;}
}

或者,按如下所示在设置中使用它:

Or, use it in settings as follows:

var settings = new JsonSerializerSettings
{
    Converters = { new PositionDictionaryConverter() },
};

var json = JsonConvert.SerializeObject(root, settings);

当然,转换器会假定字典键和股票代号相同.

Of course the converter assumes that the dictionary key and ticker name are identical.

演示小提琴此处.

这篇关于如何将对象模型持久化为JSON并序列化字典为其值数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆