【问题标题】:JSON Deserialize different named object into a Collection c#JSON将不同的命名对象反序列化为集合c#
【发布时间】:2013-06-18 16:05:25
【问题描述】:

我必须将给定的 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"}
}

我想将 Player 实体序列化为此类对象的集合。问题是它们并没有真正存储为 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; }
}

有什么建议吗?

【问题讨论】:

  • 到目前为止我已经尝试过了: [DataContract] public class AlbReplay { [DataMember(Name = "game")] public AlbGame Game { get;放; } [DataMember(Name = "player")] public List Players { get;放; } }
  • 你可以控制这个 JSON 吗?理想情况下,您需要获得一系列玩家。动态属性不是很有帮助!您可以序列化为动态对象,然后只查找以“播放器”开头的属性,但这不是很好。
  • 不,很遗憾,不是。如果没有其他选择,我必须这样做,到目前为止谢谢!

标签: c# json collections deserialization


【解决方案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-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"]),
        });

【讨论】:

    【解决方案2】:

    将您的 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 对象设为静态且可重用将是我的第一步。

    【讨论】:

    • 感谢您的回答!好吧,如果没有其他办法,我必须在反序列化之前进行一些字符串操作。奇怪的是,我必须用很多文件来做这件事。我害怕我的表现:)
    • @John Smuf - 使用这种 JSON 总是一个问题,它需要在某个时候进行转换。我将针对您的具体情况的正则表达式替换添加到我的答案中。您可以尝试的另一件事是 .NET 的动态对象,然后您可以转换为 Dictionary 并将所有具有以 player_ 开头的键的对象转换为 Player 类,不确定它是否会工作甚至更快不过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多