我有一组格式有趣的JSON,我需要使用C#读取,在我的情况下,特别是使用JSON.NET
,尽管也可以使用System.Text.Json
来完成。
数据的结构与此类似:
[
{
"Name": "Name A",
"Value": "Apples"
},
{
"Name": "Name B",
"Value": {
"key1": "value1",
"key2": "value2"
}
}
]
简而言之,形状有些不同的对象数组,特别是"Value"属性是不同的。如果有帮助的话,我只对具有键/值(Dictionary<string, string>
(类型的Value数据的记录感兴趣。
将这些数据读取为某种类型化表示的最佳(在这种情况下最简单(方法是什么?我说打字是因为这是我想使用的,但严格来说,这不是的要求。
类似于">嘿,JSON.NET,请给我所有"Value"为键/值类型的记录,如果可能的话,作为对象结构,其中Value具体化为类型Dictionary<字符串,字符串>对象。如果有帮助的话,其他记录可能会被丢弃。谢谢";。
如果能以某种方式使用POCO对象来实现这一点,那将是非常棒的。
一种可能的方法是使用JsonConverter
子类。
例如,如果找到JTokenType.Object
,则这可以包含具有键值对的Dictionary<string, string>
,并且在任何其他情况下返回空字典。当然可以根据需要进行定制。
字典值转换器
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class DictionaryValueConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Dictionary<string, string>));
}
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue,
JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
return token.Type == JTokenType.Object
? token.ToObject<Dictionary<string, string>>()
: new Dictionary<string, string>();
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
项目
数组的Item
看起来像这样:
using Newtonsoft.Json;
public class Item
{
public string Name { get; set; }
[JsonConverter(typeof(DictionaryValueConverter))]
public Dictionary<string, string> Value { get; set; }
}
测试
你可以这样称呼它:
using Newtonsoft.Json;
public static class Program
{
static void Main()
{
string json = @"
[
{
""Name"": ""Name A"",
""Value"": ""Apples""
},
{
""Name"": ""Name B"",
""Value"": {
""key1"": ""value1"",
""key2"": ""value2""
}
}
]
";
var list = JsonConvert.DeserializeObject<List<Item>>(json);
if (list == null) return;
foreach (var item in list)
{
Console.WriteLine($"name: {item.Name}");
if (item.Value.Count == 0)
{
Console.WriteLine("no value");
}
foreach (var (key, value) in item.Value)
{
Console.WriteLine($" -> Key = {key}, Value = {value}");
}
Console.WriteLine();
}
}
}
上述示例代码的输出为:
name: Name A
no value
name: Name B
-> Key = key1, Value = value1
-> Key = key2, Value = value2
如上所述,该方法可以根据需要进行定制。
尝试这个
var jsonParsed = JArray.Parse(json);
var items = new List<Item>();
foreach (JObject item in jsonParsed)
{
var name = string.Empty;
foreach (var prop in item.Properties())
{
if (prop.Value.Type.ToString() != "Object")
{
if (prop.Name == "Name") name = (string)prop.Value;
continue;
}
items.Add(new Item
{
Name = name,
Value = prop.Value.ToObject<Dictionary<string, string>>()
});
}
}
结果
[
{
"Name": "Name B",
"Value": {
"key1": "value1",
"key2": "value2"
}
}
]
类
public class Item
{
public string Name { get; set; }
public Dictionary<string, string> Value { get; set; }
}