There is a parameter in DataContractSerializer constructor that can be set to true to preserve the object references.
I found two ways to fix that issue:
1- using [DataContract(IsReference = true)] attribute on the entity
[DataContract(IsReference = true)] public class Customer { [DataMember] public string Name { get; set; } [DataMember] public Order Order { get; set; } }
2- using custom attribute on service operations
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using System.Runtime.Serialization; namespace MyWcfService { [Serializable] public class DataContractSerializerCircularReferenceFixAttribute : Attribute, IOperationBehavior { private readonly DataContractSerializerCircularReferenceFixOperationBehavior _innerOperationBehavior; public DataContractSerializerCircularReferenceFixAttribute() { } public DataContractSerializerCircularReferenceFixAttribute(OperationDescription operation) { _innerOperationBehavior = new DataContractSerializerCircularReferenceFixOperationBehavior(operation); } public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { if (_innerOperationBehavior == null) return; (_innerOperationBehavior as IOperationBehavior).AddBindingParameters(operationDescription, bindingParameters); } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { ReplaceDataContractSerializerOperationBehavior(operationDescription); } public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { ReplaceDataContractSerializerOperationBehavior(operationDescription); } public void Validate(OperationDescription operationDescription) { if (_innerOperationBehavior == null) return; (_innerOperationBehavior as IOperationBehavior).Validate(operationDescription); } private void ReplaceDataContractSerializerOperationBehavior(OperationDescription description) { var operationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (operationBehavior == null) return; description.Behaviors.Remove(operationBehavior); description.Behaviors.Add(new DataContractSerializerCircularReferenceFixOperationBehavior(description)); } } class DataContractSerializerCircularReferenceFixOperationBehavior : DataContractSerializerOperationBehavior { public DataContractSerializerCircularReferenceFixOperationBehavior(OperationDescription operation) : base(operation) { } public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes) { return new DataContractSerializer(type, name, ns, knownTypes, this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject, true, this.DataContractSurrogate); } public override XmlObjectSerializer CreateSerializer(Type type, System.Xml.XmlDictionaryString name, System.Xml.XmlDictionaryString ns, IList<Type> knownTypes) { return new DataContractSerializer(type, name, ns, knownTypes, this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject, true, this.DataContractSurrogate); } } } // WCF Service-------------------------------------- [ServiceContract] public class MyService { [OperationContract] [DataContractSerializerCircularReferenceFix] public Customer GetCustomer(string id){ //code here } }