反序列化动态JSON文件C#NewtonSoft.JSON

正在进行反序列化动态JSON文件,该文件可能包含2个单独的类,我不知道数组中将包含哪种类型的数据。

问题是,我将根对象反序列化为“Base”类型,“subtests”对象被反序列化为“Subtest”,但“subtests”数组可以是“Base”类型或“Subtest”类型。

问题:我如何以编程方式确定如果对象包含“subtest”,我将反序列化为Base,如果不包含,则应将其反序列化为“Subtest”?

因为我的时间很短,所以我非常感谢这方面的帮助。

(编辑:添加注释以显示每个对象应反序列化的类型)以下是一个示例(JSON DATA):

{ // Deserializes to type "Base" "host": "123456", "last_time": "2014-09-15 07:04:49.205000", "name": "myName", "result": "FAIL", "serial": "12345", "start_time": "2014-09-15 06:53:36.976000", // Deserializes to type "List" "subtests": [ { "data": { "moredata": { "ver": "123", "real": 123 } }, "description": "Description of Data", "host": "123456", "last_time": "2014-09-15 20:32:31.095000", "name": "testname.py", "result": "PASS", "start_time": "2014-09-15 20:32:25.873000", "version": "2.014.09.15" }, { // Nested within Subtest Array, Should deserialize to type "Base" again "host": "123456", "last_time": "2014-09-15 07:04:49.205000", "name": "name of test suite", "result": "FAIL", "start_time": "2014-09-15 06:53:36.976000", //Should deserialize to type "List" "subtests": [ { "description": "Description of Data", "host": "123456", "last_time": "2014-09-15 06:53:40.440000", "name": "testname.py", "result": "FAIL", "start_time": "2014-09-15 06:53:36.976000", "version": "2.014.09.15" }, { "description": "Test Description", "host": "123456", "last_time": "2014-09-15 06:54:34.905000", "name": "testname.py", "result": "PASS", "start_time": "2014-09-15 06:54:34.827000", "version": "2.014.09.15" }, { "host": "123456", "last_time": "2014-09-15 06:55:01.156000", "name": "testname.py", "result": "FAIL", "start_time": "2014-09-15 06:55:01.156000", "version": "2.014.09.15" }, ], "version": "1.45" } ], "version": "1.23" } 

示例(代码):

 public class Base{ public string host { get; set; } public DateTime last_time { get; set; } public string name { get; set; } public string result { get; set; } public string serial { get; set; } public DateTime start_time { get; set; } public List subtests { get; set; } public string version { get; set; } } public class Subtest { [JsonProperty("data")] public JObject Data { get; set; } // CHECK [JsonProperty("description")] public string Description { get; set; } // CHECK [JsonProperty("host")] public string Host { get; set; } [JsonProperty("info")] public List Info { get; set; } [JsonProperty("last_time")] public DateTime LastRunTime { get; set; } [JsonProperty("name")] public string TestName { get; set; } [JsonProperty("result")] public string SubtestRunResult { get; set; } [JsonProperty("start_time")] public DateTime StartTime { get; set; } [JsonProperty("trace")] public List Trace { get; set; } [JsonProperty("version")] public string Version { get; set; } } 

我会修改你的类来形成一个层次结构。 我可能在这里错过了一处房产,但是你得到的照片。 重要的是转换器。

 public abstract class TestBase { public string Host { get; set; } [JsonProperty("last_time")] public DateTime LastTime { get; set; } public string Name { get; set; } public string Result { get; set; } [JsonProperty("start_time")] public DateTime StartTime { get; set; } public string Version { get; set; } } public class TestSuite : TestBase { public string Serial { get; set; } public List Subtests { get; set; } } public class Subtest : TestBase { public JObject Data { get; set; } public string Description { get; set; } } 

然后,您需要一个自定义转换器,以根据subtests属性的存在选择正确的类型:

 public class TestBaseConverter : JsonConverter { public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject obj = serializer.Deserialize(reader); TestBase result = null; if (obj["subtests"] != null) { result = new TestSuite(); } else { result = new Subtest(); } serializer.Populate(obj.CreateReader(), result); return result; } public override bool CanConvert(Type objectType) { return typeof(TestBase).IsAssignableFrom(objectType); } public override bool CanWrite { get { return false; } } public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer) { throw new NotSupportedException(); } } 

然后你会像这样使用它:

 TestSuite suite = JsonConvert.DeserializeObject( json, new TestBaseConverter()); 

我最终做的是将一个List属性添加到我的Subtest类中,并在递归的foreach循环函数中检查空值。 不像我希望的那样漂亮,但比解析它并单独反序列化每个subtest对象更好。

 private static void GetSubtest(List subtestList) { foreach (var subtest in subtestList) { if (subtest.Subtests != null) { GetSubtest(subtest.Subtests); } else { // add data to Vertica cluster } } } 

漫长的一天,真的很感谢所有你想要帮助的人。 JSON的新手,所以我无法理解它。 希望这有助于将来的其他人。 如果您需要更多解释,请在此处发表评论。