【发布时间】:2019-02-06 09:44:17
【问题描述】:
我有以下 C# 对象:
public abstract partial class ClientTreeNode {
public int ID { get; internal set; }
public string Question { get; internal set; }
public List<ClientTreeNode> Children { get; internal set; }
public QuestionCategories Category { get; internal set; }
public Dictionary<object, List<int>> AnswerNodes { get; internal set; }
public string Type => GetType().Name.Replace("TreeNode", "").FirstCharacterToLower();
public string CategoryText {
get {
switch (Category) {
case QuestionCategories.VisualInspection:
return "Sichtprüfung";
case QuestionCategories.MechanicalInspection:
return "Mechanische Prüfung";
case QuestionCategories.ElectricalInspection:
return "Elektrische Prüfung";
default:
return "Fehler";
}
}
}
public abstract AnswerResult Answer(JObject data);
internal static ClientTreeNode FromDatabase(int ID, out int TotalChildNodes) {
// ....
}
internal static int SumUpChildNodes(List<int> nodeIDs) {
using (var db = new DatabaseEntities()) {
return db.TreeNodes
.Where(tn => nodeIDs.Contains(tn.ID))
.Sum(tn => tn.TotalChildNodes);
}
}
[JsonConverter(typeof(StringEnumConverter), true)]
public enum QuestionCategories {
VisualInspection,
MechanicalInspection,
ElectricalInspection
}
}
public class YesNoTreeNode : ClientTreeNode {
public bool Result { get; internal set; }
public override AnswerResult Answer(JObject data) {
if (data["result"].Type != JTokenType.Boolean)
throw new ArgumentException("The provided answer was invalid.");
Result = data["result"].Value<bool>();
Children = new List<ClientTreeNode>();
foreach (var childNodeID in AnswerNodes[Result])
Children.Add(FromDatabase(childNodeID, out _));
return new AnswerResult(SumUpChildNodes(AnswerNodes[!Result]), Children);
}
}
JSON 文件如下所示:
{"AnswerNodes":{"True":[4],"False":[5]}}
有时,它可以更高级一点,像这样。但并非在所有情况下都是强制性的:
{"Result":false,"ID":0,"Question":null,"Children":null,"Category":"visualInspection","AnswerNodes":{"True":[4],"False":[5]},"Type":"yesNo","CategoryText":"Sichtprüfung"}
当我尝试使用以下代码对其进行解码时,所有值都被填充,除了 AnswerNodes 字典。这总是为空:
JsonConvert.DeserializeObject<YesNoTreeNode>(node.NodeOptionsJSON);
// This is a workaround:
if (ret.AnswerNodes is null)
ret.AnswerNodes = JObject.Parse(node.NodeOptionsJSON)["AnswerNodes"].ToObject<Dictionary<object, List<int>>>();
即使在以下测试场景中,它也不起作用。因此,我可以排除这是由于格式错误的 JSON 代码造成的。
ret = loadFromJSON ? JsonConvert.DeserializeObject<YesNoTreeNode>(node.NodeOptionsJSON) : new YesNoTreeNode();
// At this point, ret.AnswerNodes is null
ret.AnswerNodes = new Dictionary<object, List<int>>();
ret.AnswerNodes.Add(1, new List<int>() { 4 });
ret.AnswerNodes.Add(2, new List<int>() { 5 });
var test = JsonConvert.SerializeObject(ret);
var test2 = JsonConvert.DeserializeObject<YesNoTreeNode>(test);
有没有办法让 DeserializeObject 方法首先正确解码对象?
【问题讨论】:
-
您没有发布 JSON 字符串。
AnswerNodes标记的内容很可能不能被视为您想要的类型。 JSON 无论如何只能将字符串作为标签,因此您应该使用Dictionary<string,....> -
@PanagiotisKanavos 如果您查看我的最后一个示例(带有 test 和 test2 的示例),它甚至无法解码它自己创建的 JSON。我将在上面添加一些示例 JSON。
-
发布 JSON 字符串,不要强迫人们猜测。我再说一遍,你不能有非字符串标签,所以使用
Dictionary<string,...是不寻常的 -
@PanagiotisKanavos 我刚刚在上面编辑了我的问题。
-
Category是一个 string 但您的班级需要一个 QuestionCategories。那是一个枚举吗?
标签: c# json json.net deserialization json-deserialization