Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular References and WCF

I have generated my POCO entities using POCO Generator, I have more than 150+ tables in my database. I am sharing POCO entities all across the application layers including the client. I have disabled both LazyLoading and ProxyCreation in my context.I am using WCF on top of my data access and business layer.

Now, When I return a poco entity to my client, I get an error saying "Underlying connection was closed" I enabled WCF tracing and found the exact error : Contains cycles and cannot be serialized if reference tracking is disabled.

I Looked at MSDN and found solutions like setting IsReference=true in the DataContract method atttribute but I am not decorating my POCO classes with DataContracts and I assume there is no need of it as well. I won't be calling that as a POCO if I decorate a class with DataContract attribute

Then, I found solutions like applying custom attribute [CyclicReferenceAware] over my ServiceContracts.That did work but I wanted to throw this question to community to see how other people managed this and also why Microsoft didn't give built in support for figuring out cyclic references while serializing POCO classes

like image 529
Kunal Avatar asked Feb 11 '11 09:02

Kunal


1 Answers

You already mentioned the approach, but I use this attribute

public class ReferencePreservingDataContractFormatAttribute : Attribute, IOperationBehavior
    {
        #region IOperationBehavior Members
        public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
        {
            IOperationBehavior innerBehavior = new ReferencePreservingDataContractSerializerOperationBehavior(description);
            innerBehavior.ApplyClientBehavior(description, proxy);
        }

        public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
        {
            IOperationBehavior innerBehavior = new ReferencePreservingDataContractSerializerOperationBehavior(description);
            innerBehavior.ApplyDispatchBehavior(description, dispatch);
        }


        public void Validate(OperationDescription description)
        {
        }
    #endregion
}

} ...and reference on an operation on the Service like so;

[OperationContract]
[ReferencePreservingDataContractFormat]
IList<SomeObject> Search(string searchString);

FYI - would like to give credit where it's due, but did not record where I originally saw the above approach.

Edit:

I believe source of the code is from this blog post.

like image 157
Christoph Avatar answered Oct 15 '22 21:10

Christoph