簡體   English   中英

如何使用 JSON.NET 將 JSON 數組中的 object 名稱用作屬性值?

[英]How can I use the object name in a JSON array as a property value using JSON.NET?

我有以下 JSON 塊(從完整的 JSON 中提取以簡化問題):

 "statistics": [
  {
    "Strength": {
      "min": 16,
      "max": 20
    }
  },
  {
    "Dexterity": {
      "min": 16,
      "max": 20
    }
  }]

我想將“統計”數組反序列化為“統計”對象的 C# 數組,但我找不到如何做到這一點......每個統計的關鍵 object 可以是任何東西:“強度”、“運氣” ","Dexterity" 等等,每個鍵都是唯一的。

C# 數據 object 將是這樣的:

public class Container
{
    public Statistic[] Statistics { get; set; }
}

public class Statistic
{
    //Contains the name of the statistic
    public string Name { get; set; }
    public int Min { get; set; }
    public int Max { get; set; }
}

也許我可以通過刪除Name屬性並創建所有可能的統計類來使用某種多態性,但這會破壞我的代碼的適應性。

十分感謝。

您可以使用簡單的JsonConverter為您的Statistic class 處理這個棘手的 JSON ,如下所示:

class StatisticConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Statistic);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        JProperty prop = jo.Properties().First();
        Statistic stat = new Statistic
        {
            Name = prop.Name,
            Min = (int)prop.Value["min"],
            Max = (int)prop.Value["max"]
        };
        return stat;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用它,向Statistic class 添加一個[JsonConverter]屬性,它應該可以按預期工作:

[JsonConverter(typeof(StatisticConverter))]
public class Statistic
{
    public string Name { get; set; }
    public int Min { get; set; }
    public int Max { get; set; }
}

這是一個工作演示: https://dotnetfiddle.net/H7wR0g

如果您不能(或不想)將屬性添加到Statistic class,您還可以通過將轉換器傳遞給DeserializeObject方法來使用轉換器,如下所示:

var container = JsonConvert.DeserializeObject<Container>(json, new StatisticConverter());

小提琴: https://dotnetfiddle.net/UTLzBk

鑒於提供的 JSON,我們不能直接將 go 用於Dictionary結構,這是因為我們有一個對象數組,其中每個Statistic的屬性名稱應為屬性Name

為了避免處理自定義轉換器,這里有一個快速(非生產就緒)解決方案,可以為您提供一個良好的起點。 這個想法是將其反序列化為dynamic ,然后將statistics object 提取為JArray並從那里構建您的結果結構。

請注意,我沒有檢查 null 的任何內容,因此只要輸入格式正確(您需要 NuGet 的Newtonsoft.Json ),它就可以工作。

using System;
using System.Linq;
using Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace StackOverflow
{
    internal class Program
    {
        private static readonly string _inputJson =
            @"
{
    ""statistics"": [
        {
            ""Strength"": {
                ""min"": 16,
                ""max"": 20
            }
        },
        {
            ""Dexterity"": {
                ""min"": 16,
                ""max"": 20
            }
        }]
}
";

        private static void Main(string[] args)
        {
            var tempObject = JsonConvert.DeserializeObject<dynamic>(_inputJson).statistics as JArray;

            var result = new Container
            {
                Statistics = tempObject.Select(obj =>
                {
                    var token = obj.First as JProperty;
                    var stats = token.Value;
                    return new Statistic
                    {
                        Name = token.Name,
                        Min = Convert.ToInt32((stats["min"] as JValue).Value),
                        Max = Convert.ToInt32((stats["max"] as JValue).Value)
                    };
                }).ToArray()
            };

            foreach (var stat in result.Statistics) Console.WriteLine($"{stat.Name} = ({stat.Min}, {stat.Max})");
        }
    }
}

namespace Models
{
    public class Container
    {
        public Statistic[] Statistics { get; set; }
    }

    public class Statistic
    {
        //Contains the name of the statistic
        public string Name { get; set; }
        public int Min { get; set; }
        public int Max { get; set; }
    }
}

這是我得到的 output:

力量 = (16, 20)

敏捷 = (16, 20)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM