C#JSON.NET - 反序列化使用不寻常数据结构的响应
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#JSON.NET - 反序列化使用不寻常数据结构的响应相关的知识,希望对你有一定的参考价值。
我在查找以特定格式反序列化某些JSON数据的干净(尽可能)方法时遇到了一些麻烦。我想将数据反序列化为强类型数据对象类,关于此的具体细节非常灵活。以下是数据的示例:
{
"timestamp": 1473730993,
"total_players": 945,
"max_score": 8961474,
"players": {
"Player1Username": [
121,
"somestring",
679900,
5,
4497,
"anotherString",
"thirdString",
"fourthString",
123,
22,
"YetAnotherString"],
"Player2Username": [
886,
"stillAstring",
1677,
1,
9876,
"alwaysAstring",
"thirdString",
"fourthString",
876,
77,
"string"]
}
}
我不确定的具体部分是:
- 球员的集合会被视为字典吗?用户名可以作为键,但是值会让我失望,因为它将是字符串和整数值的混合集合。
- 玩家完全由未命名的值组成。我几乎总是使用已命名属性和值的JSON数据(例如,最顶层的timestamp,total_players等)
假设我有一个这样的顶级课程:
public class ScoreboardResults
{
public int timestamp { get; set; }
public int total_players { get; set; }
public int max_score { get; set; }
public List<Player> players { get; set; }
}
鉴于它基本上是用户名作为键的键/值,并且值是混合整数和字符串的集合,Player对象会是什么样子?每个玩家元素的数据总是以相同的顺序,所以我知道集合中的第一个值是他们的UniqueID,第二个值是玩家描述等。我希望玩家类是这样的:
public class Player
{
public string Username { get; set; }
public int UniqueID { get; set; }
public string PlayerDescription { get; set; }
....
....
.... Following this pattern for all of the values in each player element
....
....
}
我确信使用JSON.NET这是一个非常简单的事情,这就是为什么我想避免我对如何实现这一点的任何想法。我想出的将是不优雅的,并且在序列化过程中可能在某种程度上容易出错。
编辑
以下是使用snow_FFFFFF建议的过去作为JSON类时生成的类:
public class Rootobject
{
public int timestamp { get; set; }
public int total_players { get; set; }
public int max_score { get; set; }
public Players players { get; set; }
}
public class Players
{
public object[] Player1Username { get; set; }
public object[] Player2Username { get; set; }
}
我不清楚的是如何将“players”元素中的JSON数据反序列化为List,其中Player1Username是Player对象上的简单字符串属性。至于混合字符串和整数的集合,我相信我可以将它们放到Player对象的各个属性中而不会出现问题。
来自Deserializing JSON in Visual Basic .NET的转换器应该做你需要的,适当地从VB.NET翻译成c#:
public class ObjectToArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(T) == objectType;
}
static bool ShouldSkip(JsonProperty property)
{
return property.Ignored || !property.Readable || !property.Writable;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var type = value.GetType();
var contract = serializer.ContractResolver.ResolveContract(type) as JsonObjectContract;
if (contract == null)
throw new JsonSerializationException("invalid type " + type.FullName);
var list = contract.Properties.Where(p => !ShouldSkip(p)).Select(p => p.ValueProvider.GetValue(value));
serializer.Serialize(writer, list);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = JArray.Load(reader);
var contract = serializer.ContractResolver.ResolveContract(objectType) as JsonObjectContract;
if (contract == null)
throw new JsonSerializationException("invalid type " + objectType.FullName);
var value = existingValue ?? contract.DefaultCreator();
foreach (var pair in contract.Properties.Where(p => !ShouldSkip(p)).Zip(token, (p, v) => new { Value = v, Property = p }))
{
var propertyValue = pair.Value.ToObject(pair.Property.PropertyType, serializer);
pair.Property.ValueProvider.SetValue(value, propertyValue);
}
return value;
}
}
接下来,将转换器添加到Player
类,并使用JsonPropertyAttribute.Order
指示每个属性的顺序:
[JsonConverter(typeof(ObjectToArrayConverter<Player>))]
public class Player
{
[JsonProperty(Order = 1)]
public int UniqueID { get; set; }
[JsonProperty(Order = 2)]
public string PlayerDescription { get; set; }
// Other fields as required.
}
最后,声明您的根对象如下:
public class ScoreboardResults
{
public int timestamp { get; set; }
public int total_players { get; set; }
public int max_score { get; set; }
public Dictionary<string, Player> players { get; set; }
}
请注意,我已将Username
从Player
类中移除到字典中,作为键。
一个好的入门方法是让visual studio根据JSON生成你的类。打开一个空白的类文件,然后转到EDIT - > PASTE SPECIAL - > PASTE JSON As CLASSES。
这将生成一个包含必要类的文件,以序列化/反序列化您的JSON。
试试这个
创建一个如下所示的类
注意:您可以在visual studio中使用“选择性粘贴”选项来生成与JSON相关的所有类
编辑 - >选择性粘贴 - >将Json粘贴为类
它将创建与JSON相关的所有类
注意:请参考this我已经回答过类似的问题..
以上是关于C#JSON.NET - 反序列化使用不寻常数据结构的响应的主要内容,如果未能解决你的问题,请参考以下文章
使用JSON.NET反序列化json - 无法反序列化,因为类型需要一个JSON数组c#
C# 使用Json.NET对数据进行序列化和反序列化 | c# json serialize and deserialize using json.net JsonConvert