Newtonsoft Json序列化程序无法使用从List继承的自定义类

时间:2017-06-30 14:02:57

标签: c# json json.net

为什么这个类的实例没有正确序列化?

[JsonObject]
public class CharCollection : List<char> {

  [JsonConstructor]
  public CharCollection(string key) {
    Key = key;      
  }

  public string Key { get; }    

}

但是,使用时序列化

JsonConvert.SerializeObject(new CharCollection("CarriageReturn"){'\r'});

不存储实际字符,只存储Key属性和其他信息......实际字符在哪里?

{"Key":"CarriageReturn","Capacity":4,"Count":1}

2 个答案:

答案 0 :(得分:2)

对于类似于此的类/结构,你可能会更好:

public class CharCollection
{
    public CharCollection(string key, IEnumerable<char> characters = null) 
    {
        Key = key;      
        Characters = new List<char>();

        if(characters != null)
        {
            Characters.AddRange(characters);
        }
    }

    public List<char> Characters { get; set; }

    public string Key { get; }   

    public int Count { get { return Characters.Count; } }

    public int Capacity { get { return Characters.Capacity; } } 

}

修改

基于您的评论,您似乎需要Dictionary<string, List<char>>

Dictionary<string, List<char>> dict= new Dictionary<string, List<char>>();

dict.Add("CarriageReturn", new List<char>() { '\r' });

这将为您提供如下所示的json:

{ "CarriageReturn":["\r"] }

小提琴here

答案 1 :(得分:0)

我同意@maccettura他的解决方案是最好的,但是如果你想自定义编写器就可以做到。

[JsonConverter(typeof(CharArraySerializer))]
        public class CharArray : List<char>
        {
            public string Key { get; }

            public CharArray(string key)
            {
                Key = key;
            }

            public CharArray(string key,List<char> list):base(list)
            {
                Key = key;
            }
        }

        public class CharArraySerializer : JsonConverter
        {
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var array = value as CharArray;

                writer.WriteStartObject();
                writer.WritePropertyName("key");
                writer.WriteValue(array.Key);

                writer.WritePropertyName("data");
                serializer.Serialize(writer, array.ToArray());

                writer.WriteEndObject();
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                 var jsonObject = JObject.Load(reader);   

                 var key = jsonObject.Value<string>("key");

                 var array = jsonObject.Value<JArray>("data").Select(t=>t.Value<char>()).ToList();

                 return new CharArray(key,array);
            }

            public override bool CanConvert(Type objectType)
            {
                return typeof(CharArray).IsAssignableFrom(objectType);
            }
        }

你的json看起来像这样

{"key":"Key","data":["a","b"]} 

您可能需要查看属性名称以使用正确的外壳,但这适用于您想要的内容。