【问题标题】:Deserializing nested json objects. When inner object might differ反序列化嵌套的 json 对象。当内部对象可能不同时
【发布时间】: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");
        }

但返回的对象不包含数据。 我将不胜感激有关对该算法建模的任何帮助。提前致谢。

【问题讨论】:

标签: c# json serialization json.net


【解决方案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&lt;T&gt; 转换 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

输出样本

【讨论】:

  • 谢谢,这是个好主意,但对象类型实际上不是字典。我简化了对象以专注于关键部分。
猜你喜欢
  • 1970-01-01
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-06
  • 2023-01-11
  • 1970-01-01
相关资源
最近更新 更多