Maison >développement back-end >C++ >Comment mapper les propriétés JSON enfants aux propriétés de classe dans la désérialisation Newtonsoft.Json ?

Comment mapper les propriétés JSON enfants aux propriétés de classe dans la désérialisation Newtonsoft.Json ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2025-01-24 23:12:11508parcourir

How to Map Child JSON Properties to Class Properties in Newtonsoft.Json Deserialization?

Mappez les propriétés enfants aux propriétés de classe lors de la désérialisation dans Newtonsoft.Json

L'attribut

dans Newtonsoft.Json permet de mapper les noms de propriétés JSON brutes aux propriétés de classe. Cependant, dans certains cas, vous devrez peut-être mapper les sous-propriétés d'un objet JSON complexe aux propriétés simples d'une classe. [DataMember]

Méthode traditionnelle

Si vous n'avez besoin que d'une seule propriété supplémentaire, une solution consiste à analyser le JSON dans un JObject et à utiliser

et ToObject() pour remplir la classe et obtenir la propriété supplémentaire. SelectToken()

Considérons un objet JSON qui contient un attribut

complexe et une classe où seul l'attribut picture est requis : 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>

Convertisseur JSON personnalisé

Pour une solution plus élégante, vous pouvez créer un JsonConverter personnalisé qui fera fonctionner les propriétés

comme prévu. Ce convertisseur fonctionne au niveau de la classe, en utilisant la réflexion et les techniques décrites ci-dessus pour renseigner les propriétés. [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>
Pour une démonstration, considérons un objet JSON plus complexe :

<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>
Dans la classe cible ci-dessous, chaque chemin de propriété est spécifié à l'aide de l'attribut

 : [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>
Avec ces propriétés, la désérialisation devrait fonctionner de manière transparente :

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn