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


241

我很高兴使用Newtonsoft JSON库。例如,我将JObject根据.NET对象创建一个,在这种情况下为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文本,然后使用反序列化功能,但这对我来说似乎是倒退的。

Answers:


489

根据这篇文章,现在好多了:

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

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

文档:将JSON转换为类型


10
关于性能影响有什么想法吗?每次都会使用反射吗?
肖恩·罗恩

1
是否可以通过自定义JsonConverter做到这一点?
贾斯汀·斯基尔斯

3
谢谢你的提示。这对我帮助很大。让我添加一些内容:在使用type的通用方法中T,我需要result=(value is JObject) ? ((JObject)value).ToObject<T>() : (T)default(T);进行成功转换(例如- value是来自数据库的对象,可能是JObject或其他情况,结果应该为null)。
马特

@ShaunRowan玩Linqpad中的代码,它看起来确实像反射用于将属性与JSON对象中的相应字段在目标对象的“级别”上匹配。属性的名称必须与JSON字段的名称匹配,并且属性的类型必须是兼容的类型。
BobbyA

jobject.ToObject(myObject.GetType())在您不知道对象类型的情况下使用。
Tohid

45

从文档中我发现了这一点

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的最新版本,并且不需要自定义序列化,请参见上面的TienDo的答案(如果支持我:P,则请参见下面的答案),这更为简洁。


2
我需要使用这种方法(而不是简写形式)来传递自定义序列化设置。
贾斯汀·卡迪科特

我正在搜寻的确切ans
Mark-VII

2

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

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

这看起来就像被接受的答案
jpaugh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.