Reputation: 5900
I have a basic object that I am sending over the wire via WCF. It's intended purpose it to help populate a Tree of data. Here's the basic structure:
[DataContract]
public class ProjectTreeNode
{
private IList<ProjectTreeNode> _children = new List<ProjectTreeNode>();
[DataMember]
public int ParentCategoryID { get; set; }
[DataMember]
public bool IsProject { get; set; }
[DataMember]
public int ProjectID { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public ProjectTreeNode Parent { get; set; }
[DataMember]
public IList<ProjectTreeNode> Children
{
get { return _children; }
set { _children = value; }
}
public ProjectTreeNode() { }
public ProjectTreeNode(string description, int parentCategoryID, IEnumerable<ProjectDto> projectChildren)
{
Description = description;
ParentCategoryID = parentCategoryID;
foreach (var project in projectChildren)
{
Children.Add(new ProjectTreeNode { Description = project.Description, IsProject = true, ProjectID = project.ProjectID, Parent = this });
}
}
}
Unfortunately, any time I try and retrieve a ProjectTreeNode
that has Children, I get errors from WCF (CommunicationException, but I am convinced its actually masking a serialization problem).
So this works fine:
public ProjectTreeNode TestNode()
{
return new ProjectTreeNode("Test Node", -1, new ProjectDto[0]);
}
But this receives an exception on the client side:
public ProjectTreeNode TestNode()
{
return new ProjectTreeNode("Test Node", -1, new[] { new ProjectDto { CategoryCombinationID = 123, Description = "Blah", ProjectID = 10} });
}
I know that constructors are stripped out when transferred over the wire, but I am confused why a complete object would still blow up in my face like this.
Upvotes: 2
Views: 173
Reputation: 8147
This is because you have a circular reference. I.e. Parent has link to child and child has link to parent. So you are right that this is a serialisation issue - when the object is serialised you will get exceptions as you recurse for infinity.
A simple fix is to mark the DataContract
as a Reference like so:
[DataContract(IsReference=true)]
public class ProjectTreeNode
{
// ...
}
Upvotes: 2