将不同的命名对象反序列化为一个集合
本文关键字:集合 一个 反序列化 对象 | 更新日期: 2023-09-27 18:18:50
我必须读取一个给定的JSON字符串到c#对象。到目前为止还好,但这个案子对我来说有点特殊。JSON字符串包含2个实体。一个是平面对象,另一个是列表,至少合乎逻辑,但不是真正的JSON。我希望你能帮我找到一个解决办法。
为了更好地解释它,我将向您展示我的JSON输入的一部分:
{
"game":{"GameMode":"1","IsNetworkMode":"1","NbMaxPlayer":"12","GameState":"1"},
"player_56":{"PlayerUserId":"137187","PlayerIALevel":"-1","PlayerObserver":"0"},
"player_7":{"PlayerUserId":"3440","PlayerIALevel":"-1","PlayerObserver":"0"}
}
我想把玩家实体序列化成这个类型的对象集合。问题是它们并没有真正以JSON的集合形式存储。它们的动态名称为"player_56",数字没有任何逻辑顺序,如"1,2,3"。
目前我正在使用DataContractJsonSerializer
来完成这项任务。
[DataContract]
public class AlbReplay
{
[DataMember(Name = "game")]
public AlbGame Game { get; set; }
[DataMember(Name = "player")]
public List<AlbPlayer> Players { get; set; }
}
有什么建议吗?
我不知道DataContractJsonSerializer
的范围,但可能有一个接口,你可以实现你的类来定义如何解析JSON。
但是如果你能够使用JSON。净:
public class Player
{
public int Id { get; set; }
public int PlayerUserId { get; set; }
public int PlayerIALevel { get; set; }
public int PlayerObserver { get; set; }
}
然后可以使用Linq-To-JSON:
var data = @"{
""game"":{""GameMode"":""1"",""IsNetworkMode"":""1"",""NbMaxPlayer"":""12"",""GameState"":""1""},
""player_56"":{""PlayerUserId"":""137187"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""},
""player_7"":{""PlayerUserId"":""3440"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""}
}";
JObject o = JObject.Parse(data);
IEnumerable<Player> players =
o.Children()
.Where(p => ((JProperty)p).Name.StartsWith("player"))
.Select(p =>
new Player
{
Id = int.Parse(((JProperty)p).Name.Split('_')[1]),
PlayerUserId = int.Parse((string)p.Children<JObject>().First()["PlayerUserId"]),
PlayerIALevel = int.Parse((string)p.Children<JObject>().First()["PlayerIALevel"]),
PlayerObserver = int.Parse((string)p.Children<JObject>().First()["PlayerObserver"]),
});
将JSON分解为玩家对象集合
player_8: {...}
player_99: {...}
players: [
{id: 8 ...},
{id: 99 ...}
]
如何处理JSON,一个RegEx可能就足够了。
EDIT下面是使用Regex进行字符串修改的代码。我们做了一些假设:在游戏和玩家对象中没有嵌入对象,玩家对象列表是json字符串的最后一部分。
string json_test = @"{
""game"":{""GameMode"":""1"",""IsNetworkMode"":""1"",""NbMaxPlayer"":""12"",""GameState"":""1""},
""player_56"" : {""PlayerUserId"":""137187"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""},
""player_2"": {""PlayerUserId"":""137187"",""PlayerIALevel"":""-1"",""PlayerObserver"":""0""}
}";
json_test = new Regex(@"""player_('d+)""'s*:'s*{").Replace(json_test, @"""player"" : {""Id"": $1,");
Console.WriteLine("player_##:{...} -> player:{id: ##,..}");
Console.WriteLine(json_test);
json_test = new Regex(@"""player""'s*:'s*{").Replace(json_test, @"""players"" : [{", 1);
json_test = new Regex(@"""player""'s*:'s*{").Replace(json_test, @"{");
json_test = new Regex(@"}$").Replace(json_test, @"]}");
Console.WriteLine("player:{...}, -> players: [{...},...]");
Console.WriteLine(json_test);
与所有关于速度的考虑一样,您必须对其进行测试,如果我必须优化上述内容,那么将Regex对象作为静态和可重用的将是我的第一步。