2

I'm trying to deserialize a JSON string into a custom class. I have to use reflection. I have a dictionary that I serialize, send over to an HttpPut method, deserialize the JSON string, and read the dictionary fields. Here's what I have so far:

I'm putting values into the Dictionary like this:

Dictionary<string, object> valuesToUpdate = new Dictionary<string, object>();
Person p = new Person();
p.personName = "OrigName";
p.age = "25";
p.isAlive = true;
valuesToUpdate.Add("Person", p);
valuesToUpdate.Add("Length", 64.0);

I'm using JSON to serialize it like this:

string jsonString = JsonConvert.SerializeObject(valuesToUpdate);

I then take the jsonString and send it over to a REST API PUT method. The PUT method updates various variables on a custom object based on the Key values in the dictionary using reflection (In this example I'm updating customObject.Person and customObject.Length).

The PUT call deserializes the jsonString like this:

Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);

I iterate through newFields and want to use reflection to update customObject's "Person" class. This is my HttpPut method that reads the jsonString:

[HttpPut("/test/stuff")]
public string PutContact([FromBody]dynamic jsonString)
{
    Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
    foreach (var field in newFields)
    {
        Console.WriteLine("\nField key: " + field.Key);
        Console.WriteLine("Field value: " + field.Value + "\n");

        PropertyInfo propInfo = typeof(Contact).GetProperty(field.Key);
        Type propertyType = propInfo.PropertyType;
        var value = propInfo.GetValue(contactToUpdate, null);

        if (propertyType.IsClass)
        {
            propInfo.SetValue(contactToUpdate, field.Value, null);
        }
    }
}

This generates the error:

Object of type Newtonsoft.Json.Linq.JObject' cannot be converted to type 'Person';

I've also tried using JSON's PopulateObject method but it returned this error:

Newtonsoft.Json.JsonSerializationException: Cannot populate JSON object onto type 'Person'. Path 'personName', line 1....

So basically, how can you go about taking a JSON string, converting it to a class (in my case the 'Person' class), and setting it to customObject's Person field with reflection?

Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
Roka545
  • 3,404
  • 20
  • 62
  • 106
  • Consider using [`JsonConvert.PopulateObject()`](http://www.newtonsoft.com/json/help/html/PopulateObject.htm) instead. See for instance [Modify existing object with new partial JSON data using Json.NET](https://stackoverflow.com/questions/27511675). – dbc Apr 19 '16 at 20:19
  • `PopulateObject()` should work. Can you give some additional details about the exception it threw, including the full `ToString()` output of the exception, and (ideally) a [complete example](https://stackoverflow.com/help/mcve) showing a `Person` class and some JSON that causes the exception? – dbc Apr 19 '16 at 20:27
  • The exception is due to JsonConvert deserializing complex type (`Person`) into a JObject intead of `Person`. There is no way to be aware of that when OP is deserializing the json into a `Dictionary`. – Xiaoy312 Apr 19 '16 at 20:31

1 Answers1

1
if (propertyType.IsClass)
{
    propInfo.SetValue(contactToUpdate, ((JObject)field.Value).ToObject(propertyType), null);
}
Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
  • I tried your code and get this error: The type arguments for method 'Newtonsoft.Json.Linq.JToken.ToObject(Newtonsoft.Json.JsonSerializer)' cannot be inferred from the usage. Try specifying the type arguments explicitly. – Roka545 Apr 19 '16 at 21:23
  • What's the version of Json.NET package? – Xiaoy312 Apr 19 '16 at 21:36
  • My mistake. Seems like it wasn't installed. I just installed 8.0.3. – Roka545 Apr 19 '16 at 21:49