首頁 > 後端開發 > C++ > 如何在 Newtonsoft.Json 反序列化中將子 JSON 屬性對應到類別屬性?

如何在 Newtonsoft.Json 反序列化中將子 JSON 屬性對應到類別屬性?

Mary-Kate Olsen
發布: 2025-01-24 23:12:11
原創
464 人瀏覽過

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

在Newtonsoft.Json中反序列化時將子屬性對應到類別屬性

Newtonsoft.Json中的[DataMember]屬性允許將原始JSON屬性名稱對應到類別屬性。但是,在某些情況下,可能需要將複雜JSON物件的子屬性對應到類別中的簡單屬性。

傳統方法

如果只需要一個額外的屬性,一種方法是將JSON解析為JObject,並使用ToObject()SelectToken()來填充類別並取得額外的屬性。

考慮一個JSON對象,其中包含一個複雜的picture屬性,以及一個類,其中只需要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>
登入後複製

自訂JSON轉換器

為了獲得更優雅的解決方案,可以建立一個自訂JsonConverter,使[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>
登入後複製

為了演示,考慮一個更複雜的JSON物件:

<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>
登入後複製

在下面的目標類別中,每個屬性路徑都使用[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>
登入後複製

有了這些屬性,反序列化應該可以無縫運作:

<code class="language-csharp">Person p = JsonConvert.DeserializeObject<Person>(json);</code>
登入後複製

以上是如何在 Newtonsoft.Json 反序列化中將子 JSON 屬性對應到類別屬性?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板