none
What is counted as an item in WCF ObjectGraph for DataContractSerializer?

    Question

  • Hi,

    Depending on the number of items being returned and the nesting level / circular referencing between the objects in the object graph, one may encounter the exception related MaxItemsInObjectGraph being exceeded. As the exception suggests, I understand that, the way to circumvent the exception is to change the MaxItemsInObjectGraph value in the config file or to change the object graph layout itself.

    I am trying to understand exactly what counts as an item towards the MaxItemsInObjectGraph. Searching through MSDN I couldn't find some concrete documented statement as to what exactly is an item and how this counting works.

    Appreciate more inputs on the same.

    Thanks in advance.

     

    Wednesday, December 08, 2010 7:42 AM

Answers

  • You can think of MIIOG as the number of individual references (or values, in case of value types) that the serializer needs to read (or write) when serializing (or deserializing) an object.

    See the sample code below. An instance of MyDC with an int array with 100 elements contains 102 items: 1 reference for MyDC, 1 reference for the array itself, and 100 values for each integers inside the array.

    Now imagine that you have an operation which takes a MyDC[] parameter (array of MyDC). If you want to serialize an array with 5 elements, each one with, respectively, 3, 5, 7, 9 and 11 elements in its IntArray member. The total number of elements in this graph would be:

    1 +  // the MyDC[] instance
    1 + 1 + 3 + // the first instance, with 3 elements in the array
    1 + 1 + 5 + // the second instance, with 5 elements in the array
    1 + 1 + 7 + // the third instance, with 7 elements in the array
    1 + 1 + 9 + // the fourth instance, with 9 elements in the array
    1 + 1 + 11 = // the fifth instance, with 11 elements in the array

    46.

    Does it make sense?

      public class Post_12e09a40_df41_4bf7_8462_c40df68af3d5
      {
        [DataContract]
        public class MyDC
        {
          [DataMember]
          public int[] IntArray { get; set; }
        }
        [ServiceContract]
        public interface ITest
        {
          [OperationContract]
          MyDC EchoDC(MyDC input);
        }
        public class Service : ITest
        {
          public MyDC EchoDC(MyDC input)
          {
            return input;
          }
        }
        static Binding GetBinding()
        {
          BasicHttpBinding result = new BasicHttpBinding();
          return result;
        }
        public static void Test()
        {
          string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
          ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
          ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
          foreach (OperationDescription od in endpoint.Contract.Operations)
          {
            DataContractSerializerOperationBehavior dcsob = od.Behaviors.Find<DataContractSerializerOperationBehavior>();
            dcsob.MaxItemsInObjectGraph = 102;
          }
          host.Open();
          Console.WriteLine("Host opened");
    
          ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
          ITest proxy = factory.CreateChannel();
    
          Console.WriteLine(proxy.EchoDC(new MyDC { IntArray = new int[100] }));
    
          ((IClientChannel)proxy).Close();
          factory.Close();
    
          Console.Write("Press ENTER to close the host");
          Console.ReadLine();
          host.Close();
        }
      }
    
    
    • Marked as answer by CPPShark Wednesday, December 08, 2010 9:27 AM
    Wednesday, December 08, 2010 9:06 AM