2013-06-18 33 views
2

我必须将给定的JSON字符串读入C#对象。到目前为止这么好,但这种情况对我来说很特别。 JSON字符串包含2个实体。一个是平面对象,第二个是列表,至少符合逻辑,但不是真正的JSON。我希望你能帮我找到解决办法。JSON将不同的命名对象反序列化为一个集合c#

为了更好地解释它,我会告诉你我的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; } 
} 

有什么建议吗?

+0

我已经试过这个至今: [DataContract] 公开课AlbReplay { [DataMember(Name =“game”)] public AlbGame Game {get;组; } [DataMember(Name =“player”)] public List Players {get;组; } } – Ian

+0

你对这个JSON有控制吗?理想情况下,您需要获得一系列球员。动态属性不是很有帮助!你可以序列化为一个动态的对象,只需查找以“player”开头的属性,但这不是很好。 – pingoo

+0

不幸的是,没有。如果没有其他的选择,我必须去这样的事情,到目前为止,谢谢! – Ian

回答

1

我不知道DataContractJsonSerializer的范围,但可能有一个接口可以在您的类上实现以定义如何解析JSON。

但是,如果你能使用JSON.Net

public class Player 
{ 
    public int Id { get; set; } 
    public int PlayerUserId { get; set; } 
    public int PlayerIALevel { get; set; } 
    public int PlayerObserver { get; set; } 
} 

然后你可以使用LINQ到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"]), 
     }); 
+0

太棒了,看起来不错,非常感谢! – Ian

1

将你的JSON压入玩家对象的集合。

player_8: {...} 
player_99: {...} 

players: [ 
    {id: 8 ...}, 
    {id: 99 ...} 
] 

如何裂伤您的JSON,正则表达式将可能足以。

编辑下面是使用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对象静态和可重复使用的将是我的第一步,如果我不得不优化上面。

+0

感谢您的回答!那么如果没有其他方法,我必须在去序列化之前进行一些字符串操作。奇怪的是,我必须用相当多的文件来做到这一点。我担心我的表现:) – Ian

+0

@John Smuf - 使用那种JSON一直是一个问题,它需要在某个时刻进行转换。我添加了正则表达式替换您的具体情况到我的答案。你可以尝试的另一件事是.NET的动态对象,然后你可以将其转换为Dictionary ,并用一个以player_开头的密钥将所有对象强制转换为Player类,不确定它是否可以工作,甚至更快虽然。 –

相关问题