如何将 JObject 反序列化为 .NET 对象

Posted

技术标签:

【中文标题】如何将 JObject 反序列化为 .NET 对象【英文标题】:How to deserialize a JObject to .NET object 【发布时间】:2011-05-25 09:31:24 【问题描述】:

我很乐意使用Newtonsoft JSON library。 例如,我会从一个 .NET 对象创建一个JObject,在这种情况下是一个 Exception 实例(可能是也可能不是子类)

if (result is Exception)
    var jobjectInstance = JObject.FromObject(result);

现在我知道该库可以将 JSON 文本(即字符串)反序列化为对象

// only works for text (string)
Exception exception = JsonConvert.DeserializeObject<Exception>(jsontext); 

但我正在寻找的是:

// now i do already have an JObject instance
Exception exception = jobjectInstance.????

很明显,我可以从 JObject 返回 JSON 文本,然后使用反序列化功能,但这对我来说似乎倒退了。

【问题讨论】:

【参考方案1】:

从文档中,我发现了这个:

JObject o = new JObject(
   new JProperty("Name", "John Smith"),
   new JProperty("BirthDate", new DateTime(1983, 3, 20))
);

JsonSerializer serializer = new JsonSerializer();
Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person));

Console.WriteLine(p.Name);

Person 的类定义应与以下兼容:

class Person 
    public string Name  get; internal set; 
    public DateTime BirthDate  get; internal set; 

如果您使用的是 JSON.net 的最新版本并且不需要自定义序列化,请参阅Tien Do's answer,更简洁。

【讨论】:

我需要使用这种方法,而不是简写,才能传递自定义序列化设置。【参考方案2】:

根据这个post,现在好多了:

// pick out one album
JObject jalbum = albums[0] as JObject;

// Copy to a static Album instance
Album album = jalbum.ToObject<Album>();

文档:Convert JSON to a Type

【讨论】:

对这里的性能影响有什么想法吗?每次都会使用反射吗? 是否可以使用自定义 JsonConverter 来做到这一点? 感谢您的提示。这对我帮助很大。让我补充一点:在我使用类型 T 的通用方法中,我需要类似 result=(value is JObject) ? ((JObject)value).ToObject&lt;T&gt;() : (T)default(T); 的东西才能成功转换它(注意 - value 是来自数据库的对象,可能是 JObject 或其他东西在这种情况下,结果应该为空)。 @ShaunRowan 在 Linqpad 中玩弄代码,看起来确实使用反射来匹配目标对象中与 JSON 对象中相应字段相同“级别”的属性。您的属性名称必须与 JSON 字段的名称匹配,并且您的属性类型必须是兼容的类型。 如果您不知道对象类型,请使用jobject.ToObject(myObject.GetType())【参考方案3】:

为时已晚,以防万一有人在寻找另一种方式:

void Main()

    string jsonString = @"
  'Stores': [
    'Lambton Quay',
    'Willis Street'
  ],
  'Manufacturers': [
    
      'Name': 'Acme Co',
      'Products': [
        
          'Name': 'Anvil',
          'Price': 50
        
      ]
    ,
    
      'Name': 'Contoso',
      'Products': [
        
          'Name': 'Elbow Grease',
          'Price': 99.95
        ,
        
          'Name': 'Headlight Fluid',
          'Price': 4
        
      ]
    
  ]
";

    Product product = new Product();
    //Serializing to Object
    Product obj = JObject.Parse(jsonString).SelectToken("$.Manufacturers[?(@.Name == 'Acme Co' && @.Name != 'Contoso')]").ToObject<Product>();

    Console.WriteLine(obj);



public class Product

    public string Name  get; set; 
    public decimal Price  get; set; 

【讨论】:

这看起来和accepted answer一模一样。

以上是关于如何将 JObject 反序列化为 .NET 对象的主要内容,如果未能解决你的问题,请参考以下文章

将JSON字符串反序列化为指定的.NET对象类型

如何将 JSON 反序列化为具有多个 List<T> 参数的 .NET 对象?

如何正确地将 asp.net 核心模型状态错误反序列化为 xamarin 形式的对象

如何使用json.net自定义反序列化为对象

将 JSON 命名属性反序列化为 .Net 对象

使用 Json.net 将 JSON 对象反序列化为动态对象