问题
我遇到的问题是,在构建它之后返回“treeNode”时,它在通过API向下发送时不会序列化。对象[和嵌套元素]在调试时看起来很棒,但是当浏览器接收到树的数据时,它会转换为空数组(当有更深层嵌套的子节点时,某些数组具有正确的长度)。任何帮助表示赞赏,请参阅下面的代码和输出。
运行:
TreeNode<GenericClass> treeNode = new TreeNode<GenericClass>(new GenericClass() { Title = "Root", URL = null });
GenericClass Google = new GenericClass() { Title = "Google", URL = "https://www.google.com" };
GenericClass Yahoo = new GenericClass() { Title = "Yahoo", URL = "https://www.yahoo.com" };
GenericClass Bing = new GenericClass() { Title = "Bing", URL = "https://www.bing.com" };
treeNode.AddChild(Google);
treeNode.AddChild(Yahoo);
treeNode.AddChild(Bing);
// return treeNode.ToString(); <- Doesnt work
// return treeNode.ToList(); <- Doesnt work
// return JsonConvert.SerializeObject(treeNode); <-Doesnt work
return treeNode;
TreeNode(树/层次结构构建类):
public class TreeNode<T> : IEnumerable<TreeNode<T>>
{
#region Properties
public T Data { get; set; }
public TreeNode<T> Parent { get; set; }
public ICollection<TreeNode<T>> Children { get; set; }
public Boolean IsRoot
{
get { return Parent == null; }
}
public Boolean IsLeaf
{
get { return Children.Count == 0; }
}
public int Level
{
get
{
if (this.IsRoot)
{
return 0;
}
return Parent.Level + 1;
}
}
#endregion
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList<TreeNode<T>>();
this.ElementsIndex = new LinkedList<TreeNode<T>>();
this.ElementsIndex.Add(this);
}
public TreeNode<T> AddChild(T child)
{
TreeNode<T> childNode = new TreeNode<T>(child) { Parent = this };
this.Children.Add(childNode);
this.RegisterChildForSearch(childNode);
return childNode;
}
public override string ToString()
{
return Data != null ? Data.ToString() : "[data null]";
}
private ICollection<TreeNode<T>> ElementsIndex { get; set; }
private void RegisterChildForSearch(TreeNode<T> node)
{
ElementsIndex.Add(node);
if (Parent != null)
{
Parent.RegisterChildForSearch(node);
}
}
public TreeNode<T> FindTreeNode(Func<TreeNode<T>, bool> predicate)
{
return this.ElementsIndex.FirstOrDefault(predicate);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<TreeNode<T>> GetEnumerator()
{
yield return this;
foreach (var directChild in this.Children)
{
foreach (var anyChild in directChild)
{
yield return anyChild;
}
}
}
}
输出(序列化前):
答案 0 :(得分:2)
在IEnumerator
实施中,您有
yield return this;
这对我没有意义。
JSON.Net正在返回
Newtonsoft.Json.JsonSerializationException:自引用循环 检测
因为它很快就会检测到.Net将返回StackOverflowException
。这个JSON看起来怎么样?
超越原始问题的范围,为什么不应该像这样实施GetEnumerator
函数?
public IEnumerator<TreeNode<T>> GetEnumerator()
{
return this.Children.GetEnumerator()
}
从最初的一眼看,你的代码看起来就像是在计算孩子,而不是孩子。
最简单的方法是调试序列化过程。 (没有自我参考,可能需要一段时间。)
答案 1 :(得分:0)
*适合我的解决方案
<强>运行:强>
TreeNode<GenericClass> treeNode = new TreeNode<GenericClass>(new GenericClass() { Title = "Root", URL = null });
GenericClass Google = new GenericClass() { Title = "Google", URL = "https://www.google.com" };
GenericClass Yahoo = new GenericClass() { Title = "Yahoo", URL = "https://www.yahoo.com" };
GenericClass Bing = new GenericClass() { Title = "Bing", URL = "https://www.bing.com" };
treeNode.AddChild(Google);
treeNode.AddChild(Yahoo);
treeNode.AddChild(Bing);
return JsonConvert.SerializeObject(treeNode, Formatting.Indented, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
TreeNode类:
public class TreeNode<T>
{
#region Properties
public T Data { get; set; }
public TreeNode<T> Parent { get; set; }
public ICollection<TreeNode<T>> Children { get; set; }
public Boolean IsRoot
{
get { return Parent == null; }
}
public Boolean IsLeaf
{
get { return Children.Count == 0; }
}
public int Level
{
get
{
if (this.IsRoot)
{
return 0;
}
return Parent.Level + 1;
}
}
#endregion
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList<TreeNode<T>>();
this.ElementsIndex = new LinkedList<TreeNode<T>>();
this.ElementsIndex.Add(this);
}
public TreeNode<T> AddChild(T child)
{
TreeNode<T> childNode = new TreeNode<T>(child) { Parent = this };
this.Children.Add(childNode);
this.RegisterChildForSearch(childNode);
return childNode;
}
public override string ToString()
{
return Data != null ? Data.ToString() : "[data null]";
}
private ICollection<TreeNode<T>> ElementsIndex { get; set; }
private void RegisterChildForSearch(TreeNode<T> node)
{
ElementsIndex.Add(node);
if (Parent != null)
{
Parent.RegisterChildForSearch(node);
}
}
public TreeNode<T> FindTreeNode(Func<TreeNode<T>, bool> predicate)
{
return this.ElementsIndex.FirstOrDefault(predicate);
}
}
<强>返回:强>
{
"Data": {
"Title": "Root",
"URL": null
},
"Parent": null,
"Children": [
{
"Data": {
"Title": "Google",
"URL": "https://www.google.com"
},
"Children": [],
"IsRoot": false,
"IsLeaf": true,
"Level": 1
},
{
"Data": {
"Title": "Yahoo",
"URL": "https://www.yahoo.com"
},
"Children": [],
"IsRoot": false,
"IsLeaf": true,
"Level": 1
},
{
"Data": {
"Title": "Bing",
"URL": "https://www.bing.com"
},
"Children": [],
"IsRoot": false,
"IsLeaf": true,
"Level": 1
}
],
"IsRoot": true,
"IsLeaf": false,
"Level": 0
}