【问题标题】:Deserialize dynamic structure with Newtonsoft Json使用 Newtonsoft Json 反序列化动态结构
【发布时间】:2017-05-19 09:08:56
【问题描述】:

我在尝试反序列化应用程序中的“动态”JSON 结构时遇到了一些问题。

我收到一个 json 对象,它有一个字段 packages,可以作为字符串数组或“对象”数组进行评估。所以,在某些情况下,我有这样的事情:

"packages" : [ "Test", "Var" ]

还有一些我有的:

"packages" : [ {
    "id" : "9",
    "name" : "Test"
},
{
    "id" : "19",
    "name" : "Opt"
}]

在我的域类中,我尝试以这种方式定义 packages 字段:

public List<object> packages { get; set; }

但这似乎只在我反序列化字符串数组时才有效。相反,当我获取对象时,我班级中的 packages 字段被评估为 null

我该如何解决这个问题? 我可以避免仅对 packages fileld 进行反序列化并将值作为简单字符串获取吗?

注意:我也尝试这样定义字段:

public String packages { get; set; }

但我遇到了一个异常......

【问题讨论】:

标签: c# json serialization json.net


【解决方案1】:

您可以使用JToken 替换object

public class [YourClassName]
{
    public List<JToken> packages { get; set; }
}

那你可以yourObject.packages.First().ToString()

【讨论】:

  • 这是一个有趣的建议。我试试看。
【解决方案2】:

问题是您试图将 2 种不同的输入类型反序列化为 1,这不是 C# 喜欢的。 Json Parser 的返回类型必须明确定义,这意味着不可能有一个 List 有时有一个 String,有时有一些 Object

我认为处理这个问题的正确方法是首先找出你的输入是什么样的,例如使用一些Regex 表达式。找出输入的样子后,使用Json 解析器将输入解析为适合您输入的对象。

对于字符串列表,请使用:

class ParsedStrings {
    public List<String> Packages { get; set; }
}

对于对象列表,请使用:

   class ParsedObjects {
        public List<IdName> Names { get; set; }

        public class IdName {
             public string Id { get; set; }
             public string Name { get; set; }
        }
   }

由于您使用的是强类型语言,因此该输入的格式不是很好。您应该考虑使用不同的语言来解决您的问题,或者更改您的输入以更好地适应您的环境。

【讨论】:

    【解决方案3】:

    我终于解决了实现自定义JsonConverter

    public class PackagesConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            throw new NotImplementedException();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
                return null;
    
            List<string> res = new List<string>();
    
            var jsonArray = JArray.Load(reader);
            foreach (var i in jsonArray)
            {
                if (i.Count() > 1)
                {
                    var name = i["name"];
                    res.Add(name.ToString());
                }
                else
                {
                    res.Add(i.ToString());
    
                }
            }
            return res;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    

    并将其应用于我的领域:

    [JsonConverter(typeof(PackagesConverter))]
    public List<String> packages { get; set; }
    

    这工作正常...

    【讨论】:

      猜你喜欢
      • 2019-12-20
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多