【问题标题】:Cannot Deserialize Recursively a Class Hierarchy Using JSON.NET无法使用 JSON.NET 递归反序列化类层次结构
【发布时间】:2017-11-08 16:25:38
【问题描述】:

我有一个这样的类层次结构:

class Rule { }
class Condition { List<Rule> Rules { get; set; } }

忘记其余的属性。我需要使用自定义 JsonConverter 从 JSON 字符串反序列化。问题是,我有每个特定案例的代码,但我不能让它递归运行,为了照顾 Rules 属性,它的每个元素也可以是一个 Condition。 我的代码是这样的(ReadJson 方法):

var jo = JObject.Load(reader);
Rule rule = null;

if (jo["condition"] == null)
{
    rule = new Rule();
    //fill the properties for rule
}
else
{
    rule = new Condition();
    //I now want the converter to go through all the values in jo["rules"] and turn them into Rules or Conditions
}

实现这一目标的最佳方法是什么?如果发现该对象是一个条件,我尝试获取其余部分的 JSON:

var json = jo.GetValue("rule").ToString();

但是我不能像这样反序列化它,它会抛出一个异常:

var rules = JsonConvert.DeserializeObject<Rule[]>(json, this);

异常是:JsonReaderException:从 JsonReader 读取 JObject 时出错。当前 JsonReader 项不是对象:StartArray。路径'',第 1 行,位置 1。

有什么想法吗?

【问题讨论】:

  • JSON 是什么样的?
  • 当然,就像一组规则或可能的条件。像 [ { ... }, { "condition": true, ... } ]

标签: json.net json-deserialization


【解决方案1】:

你离让它工作不远了。根据 JSON 中是否存在 condition 属性实例化正确类型的对象后,您可以使用 serializer.Populate 方法填充实例。这应该自动处理递归。您确实需要将新的JsonReader 实例传递给Populate,您可以使用jo.CreateReader() 创建它。

这是转换器的外观:

public class RuleConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Rule).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jo = JObject.Load(reader);
        Rule rule = null;

        if (jo["condition"] == null)
        {
            rule = new Rule();
        }
        else
        {
            rule = new Condition();
        }

        serializer.Populate(jo.CreateReader(), rule);
        return rule;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

这是一个工作示例:https://dotnetfiddle.net/SHctMo

【讨论】:

  • 谢谢,但是当我调用 serializer.Populate: JsonReaderException : Error 从 JsonReader 读取 JObject 时,我仍然收到此异常。当前 JsonReader 项不是对象:StartArray。路径“规则”,第 1 行,位置 31。我的代码与您的代码相同。
  • 您的 JSON 是否与我发布的示例中的结构相同,或者在某种程度上有所不同?如果无法查看我正在处理的内容,就很难诊断出问题所在。你能创建一个显示问题的minimal reproducible example 吗? (最简单的方法是分叉我的示例小提琴并更改 JSON)
  • 现在可以使用了,非常感谢!我的错误,通常是这样! :-)
猜你喜欢
  • 2019-04-09
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 2013-01-10
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
相关资源
最近更新 更多