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>
<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>
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>
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!