将对象数组序列化为JSON

时间:2014-02-07 14:44:23

标签: c# .net json json.net

我有一个类型,它是字典上的包装器 - 基本上是一个键/值存储。我想将这种类型的对象数组序列化为JSON。我是JSON和Json.NET(newtonsoft.json)的新手。

我的类型有一个叫做ToJson的方法,它将字典序列化为json,如下所示

public string ToJson()
{
  return JsonConvert.SerializeObject(this.values);
}    

然后我尝试序列化这些对象的数组

var json = JsonConvert.SerializeObject(objectArray)

当然这不起作用,因为数组中的每个对象都是序列化的,我不知道如何将序列化过程指向每个对象的'ToJson'方法。

如果我传入一个Dictionary对象数组,我可以完全按照我想要的方式工作。

也许我错过了一些序列化属性?

编辑:

在阅读了更多文档后,我尝试了一种更短的方法(在考虑JsonConverter方法之前) - 使用'JsonPropertyAttribute'。将它应用于私有字典成员几乎完成了这项工作,除了我还得到序列化的成员名称,这是我不想要的。有什么方法可以通过使用JsonPropertyAttribute来序列化成员值而不是成员名吗?

2 个答案:

答案 0 :(得分:7)

为了序列化您的包装类,使其内部字典出现在JSON中,就像包装器不在那里一样,您需要一个自定义JsonConverterJsonConverter使您可以直接控制对特定类进行序列化和/或反序列化的内容。

以下是适用于您的情况的转换器。由于你没有真正提供有关你的包装类的任何细节,除了它有一个名为values的字段来保存字典,我使用反射来获取它。如果您的类具有直接操作字典的公共方法,则可以根据需要更改转换器以使用这些方法。这是代码:

class DictionaryWrapperConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(MyWrapper));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        MyWrapper wrapper = (MyWrapper)value;
        FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance);
        JObject jo = JObject.FromObject(field.GetValue(wrapper));
        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        MyWrapper wrapper = new MyWrapper();
        FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance);
        field.SetValue(wrapper, jo.ToObject(field.FieldType));
        return wrapper;
    }
}

要将自定义转换器绑定到包装类,可以在类定义中添加[JsonConverter]属性:

[JsonConverter(typeof(DictionaryWrapperConverter))]
class MyWrapper : IEnumerable
{
    Dictionary<string, string> values = new Dictionary<string, string>();

    public void Add(string key, string value)
    {
        values.Add(key, value);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return values.GetEnumerator();
    }
}

这是一个完整的演示,显示转换器正在运行,首先序列化和反序列化包装类的单个实例,然后序列化和反序列化包装器列表:

class Program
{
    static void Main(string[] args)
    {
        MyWrapper wrapper = new MyWrapper();
        wrapper.Add("foo", "bar");
        wrapper.Add("fizz", "bang");

        // serialize single wrapper instance
        string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented);

        Console.WriteLine(json);
        Console.WriteLine();

        // deserialize single wrapper instance
        wrapper = JsonConvert.DeserializeObject<MyWrapper>(json);

        foreach (KeyValuePair<string, string> kvp in wrapper)
        {
            Console.WriteLine(kvp.Key + "=" + kvp.Value);
        }
        Console.WriteLine();
        Console.WriteLine("----------\n");

        MyWrapper wrapper2 = new MyWrapper();
        wrapper2.Add("a", "1");
        wrapper2.Add("b", "2");
        wrapper2.Add("c", "3");

        List<MyWrapper> list = new List<MyWrapper> { wrapper, wrapper2 };

        // serialize list of wrappers
        json = JsonConvert.SerializeObject(list, Formatting.Indented);

        Console.WriteLine(json);
        Console.WriteLine();

        // deserialize list of wrappers
        list = JsonConvert.DeserializeObject<List<MyWrapper>>(json);

        foreach (MyWrapper w in list)
        {
            foreach (KeyValuePair<string, string> kvp in w)
            {
                Console.WriteLine(kvp.Key + "=" + kvp.Value);
            }
            Console.WriteLine();
        }
    }
}

输出:

{
  "foo": "bar",
  "fizz": "bang"
}

foo=bar
fizz=bang

----------

[
  {
    "foo": "bar",
    "fizz": "bang"
  },
  {
    "a": "1",
    "b": "2",
    "c": "3"
  }
]

foo=bar
fizz=bang

a=1
b=2
c=3

答案 1 :(得分:-1)

尝试使用任何类型的对象。它是我使用的通用JSON Serializer代码

public class JsonUtils
{
    #region
    public static string JsonSerializer<T>(T t)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, t);
        string jsonString = Encoding.UTF8.GetString(ms.ToArray());
        ms.Close();
        return jsonString;
    }
    /// <summary>
    /// JSON Deserialization
    /// </summary>
    public static T JsonDeserialize<T>(string jsonString)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        T obj = (T)ser.ReadObject(ms);
        return obj;
    }
    #endregion
}