358

I happily use the Newtonsoft JSON library. For example, I would create a JObject from a .NET object, in this case an instance of Exception (might or might not be a subclass)

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

now I know the library can deserialize JSON text (i.e. a string) to an object

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

but what I am looking for is:

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

Well it is clear that I can go from on JObject back to JSON text and then use the deserialize functionality, but that seems backwards to me.

j0zeft
  • 597
  • 2
  • 10
  • 29
Sebastian
  • 6,293
  • 6
  • 34
  • 47

3 Answers3

701

According to this post, it's much better now:

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

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

Documentation: Convert JSON to a Type

James Newton-King
  • 48,174
  • 24
  • 109
  • 130
Tien Do
  • 10,319
  • 6
  • 41
  • 42
  • 11
    Any ideas on the performance implications here? Will reflection be used every time? – Shaun Rowan Nov 02 '13 at 21:46
  • 2
    Is it possible to do this with a custom JsonConverter? – Justin Skiles Dec 16 '15 at 17:00
  • 4
    Thank you for the hint. It helped me a lot. Let me add something: In a generic method where I am using type `T`, I required something like `result=(value is JObject) ? ((JObject)value).ToObject() : (T)default(T);` to successfully convert it (note - `value` is an object coming from a database which might be a JObject or something else in which case result should be null). – Matt Feb 23 '16 at 09:15
  • @ShaunRowan Playing around with code in Linqpad, it does look like reflection is used to match the property at the same "level" of the target object as the corresponding field in the JSON object. The name of your property has to match the name of the JSON field, and the type of your property has to be a compatible type. – BobbyA Dec 18 '17 at 16:33
  • and use `jobject.ToObject(myObject.GetType())` if you don't know the object type. – Tohid Mar 23 '20 at 14:27
  • be careful using `ToObject`, it has some huge foot-guns if your JSON happens to include a date string: https://github.com/JamesNK/Newtonsoft.Json/issues/904 – Minijack Aug 16 '23 at 02:07
57

From the documentation, I found this:

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

The class definition for Person should be compatible to the following:

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

If you are using a recent version of JSON.net and don't need custom serialization, please see Tien Do's answer, which is more concise.

Pang
  • 9,564
  • 146
  • 81
  • 122
Sebastian
  • 6,293
  • 6
  • 34
  • 47
3

Too late, just in case some one is looking for another way:

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; }
}
Ivan Lopez
  • 87
  • 8
  • 1
    This looks exactly like the [accepted answer](https://stackoverflow.com/a/12208692/712526). – jpaugh Mar 03 '20 at 21:44