![](/img/trans.png)
[英]How can I use JSON.NET to handle a value that is sometimes an object and sometimes an array of the 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());
鑒於提供的 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.