从我的POCO中解决WCF中的循环引用

时间:2010-12-02 14:07:47

标签: wcf entity-framework serialization entity-framework-4 poco

我有几个类(目前为止),我正在尝试清除两者之间的循环引用,因为它正在杀死WCF的序列化。

我在WCF REST服务中使用EF和POCO是有帮助的。我已经将我的问题简化为简单的问题,这里有一个简单的例子:

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Groups
{
    [WebGet(UriTemplate = "")]
    public Message GetCollection()
    {
        var message = new Message { Body = "Test message" };
        var group = new Group { Title = "Title of group" };
        message.Group = group;
        group.Messages = new List<Message> { message };
        return message;
    }
}

public class Message
{
    public string Body { get; set; }
    public Group Group { get; set; }
}

[DataContract(IsReference = true)]
public class Group
{
    public string Title { get; set; }
    public ICollection<Message> Messages { get; set; }
}

我已将[DataContract(IsReference = true)]添加到Group类中,以便清理循环引用,但是我的返回结果最终结果如下:

<Message xmlns="http://schemas.datacontract.org/2004/07/LmApi" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Body>Test message</Body>
    <Group z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"/>
</Message>

集团的财产在哪里?我如何获得它们?

3 个答案:

答案 0 :(得分:0)

BritishDeveloper,

没有与Group关联的属性。这就是为什么你看到的是ID为1的原因。

原因是只要使用[DataContract(IsReference = true)]注释Group类,就会告诉DataContract序列化程序它不再是POCO类型。它是DataContract类型。

因此,要使用属性序列化Group,您现在需要继续使用DataMemberAttribute注释Title和Message属性。

另一种方法是使用“preserveObjectReferences”,您可以将其作为参数传递给DataContractSerializer,DataContractSerializerOperationBehavior和其他类。

希望这有帮助!

答案 1 :(得分:0)

我决定创建自己的小类,它们有一个构造函数,它接受一个实体并正确设置所有这些轻量级属性。

基本上它是类的一个非常小的副本,它只具有有效负载中所需的属性。 (显然我已经排除了问题导航属性)

答案 2 :(得分:0)

这类似于Circular References and WCF以下是针对此案例修改的答案

我遇到了同样的问题并通过将导航属性从DataContract中排除回父级来解决它

[DataContract]
public partial class Message
{

        [DataMember]
        public virtual string Body { get; set; }

        [DataMember]
        public virtual Group Group { get; set; }

}

[DataContract]
public partial class Group
{
        [DataMember]
        public virtual string Title { get; set; }

        public virtual ICollection<Message> Messages {get; set;}
}