【问题标题】:How do I deserialize this JSON?如何反序列化这个 JSON?
【发布时间】:2012-10-01 12:56:09
【问题描述】:

如何使用 Web API (JSON.Net) 反序列化以下 JSON?:

{
    "action": "edit",
    "table": "MainView",
    "id": "row_1377",
    "_group_id": "999",
    "data": {
        "ROTATION": "1", // This name/val can change
        "EQUIPMENT": [{
            "id": "6"
        },
        {
            "id": "8"
        }],
        "NOTES": ""
    }
}

data 中的值代表列并且可以更改,因此我无法使用例如一个名为“NOTES”的字符串,如json.net deserialize string to nested class

注意EQUIPMENT 包含多个值。当它以前只是像NOTES 这样的“字符串:字符串”时,这个JSON 将data 反序列化为Dictionary<string, string>,但现在我需要它像自己的字典一样工作。我最后一次尝试是反序列化为以下类型:

public class EditorSubmissionJoined
{
    public string _group_id { get; set; }
    public string action { get; set; }
    public string table { get; set; }
    public string id { get; set; }
    // "public" added below due to mistake noticed by Maggie Ying
    public Dictionary<string, object> data { get; set; } // Trouble
}

我希望object 可以包含data 中的任何内容,无论是KeyValuePair(如NOTES)还是字典(如EQUIPMENT)。

我也试过Dictionary&lt;string, ICollection&lt;Object&gt;&gt;Object,甚至ICollection&lt;Dictionary&lt;string, Object&gt;&gt;

问题是我的控制器 总是 得到 EditorSubmissionJoined,但只有空值:

public void Put(EditorSubmissionJoined ajaxSubmission) {
    // ajaxSubmission has only NULL values
}

【问题讨论】:

标签: c# asp.net-mvc-4 asp.net-web-api json.net


【解决方案1】:

有几种方法可以做到这一点。一种方法是简单地使用 JObject 并按名称访问字段,例如:jsonObject["data"]["ROTATION"]。您可以使用 JObject.Parse 将其“反序列化”,然后将 JSON 文本“解析”为 JObject

或者,您可以编写自己的 JsonConverter 并告诉 JSON.net 在反序列化特定类型(例如 JsonConverterAttribute)时使用该转换器。这需要在 ReadJson 覆盖中手动解析部分 JSON 文本,并且实际上取决于您期望的数据。

您还可以使用 Preston 评论过的动态方法。

您选择哪种方法取决于您希望事物的强类型化程度。

【讨论】:

  • 太糟糕了,JSON.net 还不支持更强类型的方法,而无需编写转换器,但我必须在系统内工作。谢谢。
  • 嗯,问题是“数据”会因某些状态而异。我想您可以定义一个“数据”类,其中包含data 可能拥有的所有可能的名称/值对。但是你有一个相当笨拙的类,很难知道哪些字段在什么上下文中有效。基于上下文改变类型的值也存在问题。 (例如,如果 VALUE 在一个上下文中是一个字符串,而在另一个上下文中是一个日期/时间)...
  • 在本例中,data 似乎可以序列化为包含KeyValuePairs 和字典集合的Object。诚然,对于一个真正动态的对象,提前不知道结果会很不方便,但在这种情况下以及大多数情况下,我认为问题还不错:For each Object in data {If it's a dictionary do X else if it's a KeyValuePair do Y.} 我相信 JSON.Net 作者对此深思熟虑,并有他的理由。
  • @CharlesBurns 是的,JObject 基本上是一个键/值对容器。该值是一个 JToken,它通常是一个 JValue 对象...
【解决方案2】:

尝试将您的“数据”属性设置为公开,您的 JSON 应该能够正确建模绑定。

【讨论】:

  • 非常敏锐。不幸的是,只有我使用 Dictionary&lt;string, object&gt; 发布的代码是私有的(哎呀),因为我的实际代码使用了一个基类,我为我的 SO 帖子简化并搞砸了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-01
  • 2021-08-22
  • 1970-01-01
  • 2021-02-13
相关资源
最近更新 更多