我在尝试反序列化应用程序中的"动态"JSON 结构时遇到了一些问题。
我收到一个 json 对象,它有一个字段 packages
,可以作为字符串数组或"对象"数组进行估值。所以,在某些情况下,我有这样的东西:
"packages" : [ "Test", "Var" ]
我有:
"packages" : [ {
"id" : "9",
"name" : "Test"
},
{
"id" : "19",
"name" : "Opt"
}]
在我的域类中,我尝试以这种方式定义包字段:
public List<object> packages { get; set; }
但这似乎仅在我反序列化字符串数组时才有效。相反,当我获取对象时,类中的packages
字段被评估为 null
。
如何解决此问题?我是否可以避免仅对packages
fileld 进行反序列化并将值作为简单字符串获取?
注意:我还尝试像这样定义字段:
public String packages { get; set; }
但我得到了一个例外...
JToken
来替换object
public class [YourClassName]
{
public List<JToken> packages { get; set; }
}
然后你可以yourObject.packages.First().ToString()
问题是您正在尝试将 2 种不同的输入类型反序列化为 1,这不是 C# 喜欢的。Json Parser
的返回类型必须明确定义,这意味着不可能有一个有时有String
,有时有Object
的List
。
我认为处理这个问题的正确方法是首先找出你的输入是什么样子的,例如使用一些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; }
}
}
由于您使用的是强类型语言,因此此输入的格式并不好。您应该考虑使用其他语言来匹配您的问题,或者更改输入以更好地适应您的环境。
我终于解决了实现自定义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; }
这工作正常...