Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix MaxItemsInObjectGraph error?

Tags:

rest

wcf

I have a RESTful WCF service and I am getting the following error: Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota.

I thought I had resolved this but apparently not. Here is my code:

I use a .SVC file that uses a custom factory like this:

<%@ ServiceHost Language="C#" Debug="true" Service="myService" Factory="myCustomWebServiceHostFactory" %>

Here is the code for the custom factory

public class myCustomWebServiceHost : WebServiceHost
{
    public myCustomWebServiceHost()
    {
    }

    public myCustomWebServiceHost(object singletonInstance, params Uri[] baseAddresses)
        : base(singletonInstance, baseAddresses)
    {
    }

    public myCustomWebServiceHost(Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
    }

    protected override void OnOpening()
    {
        foreach (var endpoint in Description.Endpoints)
        {
            var binding = endpoint.Binding as WebHttpBinding;
            if (binding != null)
            {
                const int fiveMegaBytes = 5242880;
                binding.MaxReceivedMessageSize = fiveMegaBytes;
                binding.MaxBufferSize = fiveMegaBytes;
                binding.MaxBufferPoolSize = fiveMegaBytes;
            }
        }
        base.OnOpening();
    }
}

class myCustomWebServiceHostFactory : WebServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new myCustomWebServiceHost(serviceType, baseAddresses);
    }
}

Service:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceContract]
[ServiceBehavior(MaxItemsInObjectGraph = int.MaxValue)]
public class myService
{
...service implementation code goes here
}

Client:

public class myClient
{
    WebChannelFactory<IMyService> cf;
    IMyService channel;

    public myClient()
    {
        WebHttpBinding _binding = new WebHttpBinding();
        _binding.MaxBufferPoolSize = 5000000;
        _binding.MaxBufferSize = 5000000;
        _binding.MaxReceivedMessageSize = 5000000;
        _binding.TransferMode = TransferMode.Streamed;
        _binding.ReceiveTimeout = new TimeSpan(0, 0, 30);
        _binding.ReaderQuotas.MaxArrayLength = 5000000;
        Uri _uri = new Uri("http://myserviceurl");
        cf = new WebChannelFactory<IMyService>(_binding, _uri);
        channel = cf.CreateChannel();
        foreach (OperationDescription op in cf.Endpoint.Contract.Operations)
        {
            var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
            if (dataContractBehavior != null)
            {
                dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }
    }
        ...client implementation code goes here
}

UPDATE: I have done a little troubleshooting. It seems that the serialization part is working fine on the server. I am able to do a GET from a browser and I receive back all of the data in XML format. So that is working fine. It seems to be the deserialization part that is causing the error. If you look above in the code for myClient you will see how I am attempting to set the MaxItemsInObjectGraph property for the DataContractSerializer behavior. Am I doing this correctly?

like image 897
Corey Burnett Avatar asked Jun 09 '11 19:06

Corey Burnett


2 Answers

I figured it out!!! My client code was wrong. I was setting the MaxItemsInObjectGraph after I had already created my channel. So the MaxItemInObjectGraph property had no effect on the already created channel. (This WCF stuff is so confusing to me - I am usually just copying and pasting code without really knowing what I am doing) Here is the corrected code:

        WebHttpBinding _binding = new WebHttpBinding();
        _binding.MaxBufferPoolSize = 5000000;
        _binding.MaxBufferSize = 5000000;
        _binding.MaxReceivedMessageSize = 5000000;
        _binding.TransferMode = TransferMode.Streamed;
        _binding.ReceiveTimeout = new TimeSpan(0, 0, 30);
        _binding.ReaderQuotas.MaxArrayLength = 5000000;
        Uri _uri = new Uri(http://myserviceurl);
        cf = new WebChannelFactory<IMyService>(_binding, _uri);
        foreach (OperationDescription op in cf.Endpoint.Contract.Operations)
        {
            var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
            if (dataContractBehavior != null)
            {
                dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }
        channel = cf.CreateChannel();
like image 197
Corey Burnett Avatar answered Nov 15 '22 18:11

Corey Burnett


You need to set the MaxItemsInObjectGraph on the dataContractSerializer using a behavior on both the client and service. See here for an example.

like image 40
Maurice Avatar answered Nov 15 '22 18:11

Maurice