Home >Backend Development >C++ >How to Map Child JSON Properties to Class Properties in Newtonsoft.Json Deserialization?
Map child properties to class properties when deserializing in Newtonsoft.Json
The attribute in Newtonsoft.Json allows mapping raw JSON property names to class properties. However, in some cases, you may need to map sub-properties of a complex JSON object to simple properties in a class. [DataMember]
Traditional method
If you only need one extra property, one way is to parse the JSON into a JObject and use and ToObject()
to populate the class and get the extra property. SelectToken()
attribute, and a class where only the picture
attribute is required: picture.data.url
<code class="language-json">{ "picture": { "id": 123456, "data": { "type": "jpg", "url": "http://www.someplace.com/mypicture.jpg" } } }</code>
<code class="language-csharp">public class Person { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("age")] public string Age { get; set; } public string ProfilePicture { get; set; } } string json = @"{...}"; JObject jo = JObject.Parse(json); Person p = jo.ToObject<Person>(); p.ProfilePicture = (string)jo.SelectToken("picture.data.url");</code>
Custom JSON converter
For a more elegant solution, you can create a custom JsonConverter that will make the properties work as expected. This converter operates at the class level, utilizing reflection and the techniques described above to populate properties. [JsonProperty]
<code class="language-csharp">public class JsonPathConverter : JsonConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jo = JObject.Load(reader); object targetObj = Activator.CreateInstance(objectType); foreach (var prop in objectType.GetProperties() .Where(p => p.CanRead && p.CanWrite)) { var att = prop.GetCustomAttributes(true) .OfType<JsonPropertyAttribute>() .FirstOrDefault(); string jsonPath = (att != null ? att.PropertyName : prop.Name); JToken token = jo.SelectToken(jsonPath); if (token != null && token.Type != JTokenType.Null) { object value = token.ToObject(prop.PropertyType, serializer); prop.SetValue(targetObj, value, null); } } return targetObj; } }</code>For demonstration, consider a more complex JSON object:
<code class="language-json">{ "name": "Joe Shmoe", "age": 26, "picture": { "id": 123456, "data": { "type": "jpg", "url": "http://www.someplace.com/mypicture.jpg" } }, "favorites": { "movie": { "title": "The Godfather", "starring": "Marlon Brando", "year": 1972 }, "color": "purple" } }</code>In the target class below, each property path is specified using the
attribute: [JsonProperty]
<code class="language-csharp">[JsonConverter(typeof(JsonPathConverter))] public class Person { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("age")] public int Age { get; set; } [JsonProperty("picture.data.url")] public string ProfilePicture { get; set; } [JsonProperty("favorites.movie")] public Movie FavoriteMovie { get; set; } [JsonProperty("favorites.color")] public string FavoriteColor { get; set; } } public class Movie { public string Title { get; set; } public int Year { get; set; } }</code>With these properties, deserialization should work seamlessly:
The above is the detailed content of How to Map Child JSON Properties to Class Properties in Newtonsoft.Json Deserialization?. For more information, please follow other related articles on the PHP Chinese website!