I have the following C# object:
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);
}
}
The JSON file looks like this:
{"AnswerNodes":{"True":[4],"False":[5]}}
Sometimes, it can be a little bit more advanced, like this. But it's not mandatory in all cases:
{"Result":false,"ID":0,"Question":null,"Children":null,"Category":"visualInspection","AnswerNodes":{"True":[4],"False":[5]},"Type":"yesNo","CategoryText":"Sichtprüfung"}
When I try to decode that using the following code, all values are getting filled, except for the AnswerNodes dictionary. This always becomes null:
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>>>();
Even in the following test scenario, it doesn't work. Therefore, I can except, that this is due to malformed JSON code.
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);
Is there a way to make the DeserializeObject method decode the object correctly in the first place?
AnswerNodestag can't be treated as the type you want. JSON can only have strings as tags anyway so you should use aDictionary<string,....>Dictionary<string,...is unusualCategoryis a string but your class expects a QuestionCategories. Is that an enum?