2012-10-10 47 views
3

如何反序列化JSON以下使用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<string, ICollection<Object>>,Object,甚至ICollection<Dictionary<string, Object>>

的问题是,我的控制器总是得到什么也没有,但空值EditorSubmissionJoined:

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

你应该能够反序列化为动态:http://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net –

回答

1

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

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

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

你选择哪种方法取决于你想要的东西的强类型。

+0

这太糟糕了JSON.net还不支持更强大的类型的方法,而不必写一个转换器,但我必须在系统内工作。谢谢。 –

+0

嗯,问题是“数据”取决于某些国家。我想你可以定义一个“数据”类,它包含所有可能的“数据”可能具有的名称/值对。但是,你有一个相当笨拙的课,很难知道在什么情况下哪些字段是有效的。基于上下文改变类型的值也存在问题。 (例如,如果VALUE是一个上下文中的字符串,而另一个上下文是日期/时间)...... –

+0

虽然在这个例子中看起来'data'可以被序列化为'Object',其中包含'KeyValuePair'和一系列词典。诚然,对于一个真正动态的对象来说,提前不知道结果会很不方便,但在这种情况下和大多数情况下,我认为问题并不是很糟糕:对于数据中的每个对象{如果它是字典,则执行X else else if这是一个KeyValuePair做Y.} 我确信JSON.Net作者对此有很多想法并有他的理由。 –

2

试试你的“数据”属性设置为公众和你的JSON应该能够正确模拟绑定。

+0

非常仔细。不幸的是,只有我用'Dictionary '发布的代码是私有的(oops),因为我的实际代码使用了一个基类,我为我的SO帖子简化了并且搞砸了。 –