c# – Newtonsoft Json Serializer / Deserializer – 如何使用通用对象而不是JObject?

我有一个由我正在使用的restful服务指定的JSON,它看起来像这样一个例子:

{
  "id": "97",
  "name": "Tom Production",
  "description": null,
  "parameters": [
    {
      "first_parameter_name": "First Parameter Value"
    },
    {
      "second_parameter_name": "Second Parameter Value"
    }
  ]
}

请注意,属性名称id,名称,描述和参数都是作为规范的一部分建立的.我的示例中显示为“first_parameter_name”和“second_parameter_name”的通用参数集合未指定….可以是任何内容,我想将它们映射到通用类型的对象.

我已经为此声明了一个对象:

[DataContract (Name = "MyClass")]
public class MyClass
{
    [DataMember (Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "description")]
    public string Description { get; set; }

    [DataMember(Name = "parameters")]
    public List<object> Parameters { get; set; }
}

序列化工作正常,完全符合我的预期:

        var myObject = new MyClass();
        myObject.Id = "97";
        myObject.Name = "Tom Production";
        myObject.Parameters = new List<object>();
        myObject.Parameters.Add(new { first_parameter_name = "First Parameter Value" });
        myObject.Parameters.Add(new { second_parameter_name = "Second Parameter Value" });
        string json = JsonConvert.SerializeObject(myObject);
        Console.WriteLine(json);

产生我正在寻找的JSON,就像在这篇帖子的顶部一样.

然而.

反序列化不能正常工作.如果它按照我希望的方式工作,就像我创建的那样创建泛型类型,并且下面的代码应该工作….但是它会抛出一个反射异常:

        var myNewObject = JsonConvert.DeserializeObject<MyClass>(json);

        foreach (object o in myNewObject.Parameters)
        {
            Type t = o.GetType();
            Console.WriteLine("\tType is {0}", t);
            foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                Console.WriteLine("\t\tName is {0}", pi.Name);
                Console.WriteLine("\t\tValue is {0}", pi.GetValue(o, null));
            }
        }

相反,我必须编写特定于Newtonsoft(ick)的代码来使用一种伪造的Newtonsoft反射:

        var myNewObject = JsonConvert.DeserializeObject<MyClass>(json);

        foreach (object o in myNewObject.Parameters)
        {
            var jo = o as JObject;
            if (jo != null)
            {
                foreach (JProperty prop in jo.Properties())
                {
                    Console.WriteLine("\t\tName is {0}", prop.Name);
                    Console.WriteLine("\t\tValue is {0}", prop.Value);
                }
            }
        }

有没有办法可以控制反序列化器,以便它生成正确的泛型类型而不是JProperties的JObject类型?

提前谢谢了.

最佳答案
JObjects最直接映射到Dictionary<string, object>s,因为它们每个都只是值的键集合.如果您知道该值始终是字符串,则可以将其设为Dictionary< string,string>.

[DataMember(Name = "parameters")]
public List<Dictionary<string, object>> Parameters { get; set; }

// or

[DataMember(Name = "parameters")]
public List<Dictionary<string, string>> Parameters { get; set; }

// e.g.
var myNewObject = JsonConvert.DeserializeObject<MyClass>(json);

foreach (var dict in myNewObject.Parameters)
{
    foreach (var pair in dict)
    {
        Console.WriteLine("\t\tKey is {0}", pair.Key);
        Console.WriteLine("\t\tValue is {0}", pair.Value);
    }
}

转载注明原文:c# – Newtonsoft Json Serializer / Deserializer – 如何使用通用对象而不是JObject? - 代码日志