反序列化嵌套的 json 对象。当内部对象可能不同时
Posted
技术标签:
【中文标题】反序列化嵌套的 json 对象。当内部对象可能不同时【英文标题】:Deserializing nested json objects. When inner object might differ 【发布时间】:2020-09-26 12:54:48 【问题描述】:我正在处理的服务返回嵌套在通用对象中的不同对象。这是来自服务的示例模型结果
"date":1591430887.591481,"results":["identity":"result_type_a","result":"attr_a":1591427634]
"date":1591430887.591481,"results":["identity":"result_type_b","result":"attr_b":1591427634,"attr_bb":3591457634]
"date":1591430887.591481,"results":["identity":"result_type_c","result":"attr_c":1591427634,"attr_cc":3591457634,"attr_cc":59634,"identity":"result_type_d","result":"attr_d":"rfrvr","attr_dd":"ytur"]
我尝试创建一个将结果属性声明为字符串的通用对象。并计划我可以将返回的 json 反序列化为该通用对象,检查身份属性并将结果属性中的字符串反序列化为特定对象类型。
这是对象结构
public class GeneralResponse
[JsonProperty("date")]
public double Date get; set;
[JsonProperty("results")]
public List<GenericResults> Results get; set;
public class GenericResults
[JsonProperty("identity")]
public string Identity get; set;
[JsonProperty("result")]
public string Result get; set;
要序列化/反序列化,我使用的是 Newtonsoft 库,代码如下
public static GeneralResponse SerializeResponse(string response)
return JsonConvert.DeserializeObject<GeneralResponse>(response);
不幸的是,我在反序列化通用对象时遇到了以下异常。
“解析值时遇到意外字符:.Path 'results[0].result', line 1, position 71.”
如果我将 GenericResult 的 Result 属性声明为对象,如下所示
public class GenericResults
[JsonProperty("identity")]
public string Identity get; set;
[JsonProperty("result")]
public object Result get; set;
我可以通过第一次序列化并进行第二次序列化而不会出现任何异常。
string inner_object = response.Result.ToString();
switch (type)
case ResponseTypes.type_A: return JsonConvert.DeserializeObject<ObjectTypeA>(inner_object);
case ResponseTypes.type_B: return JsonConvert.DeserializeObject<ObjectTypeB>(inner_object);
case ResponseTypes.type_C: return JsonConvert.DeserializeObject<ObjectTypeC>(inner_object);
default: throw new Exception("Unknown Response Type");
但返回的对象不包含数据。 我将不胜感激有关对该算法建模的任何帮助。提前致谢。
【问题讨论】:
看起来您的Result
应该是多态类型层次结构。要反序列化这样的类型层次结构,请参阅 Deserializing polymorphic json classes without type information using json.net 和 How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?,这看起来是重复的。同意吗?
【参考方案1】:
当您将string
与 JSON.NET 序列化一起使用时,它实际上并未使用 JSON 字符串,而是尝试解析 JSON 字符串值。
您可以改用 JObject
,它是 JSON 对象的 JSON.NETs 包装器。然后,JObject
可用于反序列化为类型或用于直接访问 JSON 属性。像这样:
switch (type)
case ResponseTypes.type_A: return response.Result.ToObject<ObjectTypeA>(inner_object);
case ResponseTypes.type_B: return response.Result.ToObject<ObjectTypeB>(inner_object);
case ResponseTypes.type_C: return response.Result.ToObject<ObjectTypeC>(inner_object);
default: throw new Exception("Unknown Response Type");
【讨论】:
我不知道这个。试过这个,但没有任何区别。还有什么我应该在代码中更改的吗? @Emre 我已经更新了我的答案以包含一个关于如何使用.ToObject<T>
转换 JObject
的示例。
感谢更新,但没有成功。我猜 inner_object 不应该在那里?【参考方案2】:
您可以使用字典来存储 结果,它看起来是多态的。例如,
public partial class GeneralResponse
[JsonProperty("date")]
public double Date get; set;
[JsonProperty("results")]
public ResultElement[] Results get; set;
public partial class ResultElement
[JsonProperty("identity")]
public string Identity get; set;
[JsonProperty("result")]
public Dictionary<string,object> Result get; set;
Working Demo
输出样本
【讨论】:
谢谢,这是个好主意,但对象类型实际上不是字典。我简化了对象以专注于关键部分。以上是关于反序列化嵌套的 json 对象。当内部对象可能不同时的主要内容,如果未能解决你的问题,请参考以下文章