[英]JSON.net object-embedded Dictionary becomes NULL
我有以下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方法正确解码对象?
没有设置任何属性,因为它们的设置器是internal set;
。 这意味着它们对其他程序集(例如Json.NET)不可见。
Linqpad中的以下代码:
public enum QuestionCategories
{
None,
visualInspection
}
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, int[]> AnswerNodes { get; internal set; }
}
public class YesNoTreeNode : ClientTreeNode {
public bool Result { get; internal set; }
}
void Main()
{
var json="{'Result':false,'ID':0,'Question':null,'Children':null,'Category':'visualInspection','AnswerNodes':{'True':[4],'False':[5]},'Type':'yesNo','CategoryText':'Sichtprüfung'}";
var obj=JsonConvert.DeserializeObject<YesNoTreeNode>(json);
JsonConvert.SerializeObject(obj).Dump();
}
产生:
{ "Result":false,
"ID":0,
"Question":null,
"Children":null,
"Category":0,
"AnswerNodes":null
}
删除internal
产生预期的结果:
{ "Result":false,
"ID":0,"Question":null,"Children":null,"Category":1,
"AnswerNodes":{"True":[4],"False":[5]}
}
默认情况下,Json.NET仅设置公共属性。
如果使用JsonProperty
属性标记属性,则可以使用内部设置器,甚至私有设置器:
public abstract partial class ClientTreeNode {
[JsonProperty]
public int ID { get; private set; }
[JsonProperty]
public string Question { get; private set; }
[JsonProperty]
public List<ClientTreeNode> Children { get; private set; }
[JsonProperty]
public QuestionCategories Category { get; private set; }
[JsonProperty]
public Dictionary<object, int[]> AnswerNodes { get; private set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.