DataContractJsonSerializer和maxItemsInObjectGraph

时间:2011-05-03 09:01:55

标签: wcf webhttpbinding datacontractjsonserializer

如何为DataContractJsonSerializer设置maxItemsInObjectGraph?

我收到错误"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."

65536的编号来自哪里。 DataContractJsonSerializer的documentation表示默认值为Int32.MaxValue。

我尝试在行为配置中设置它:

 <endpointBehaviors>
    <behavior name="WebBehavior">
      <webHttp />
      <dataContractJsonSerializer maxItemsInObjectGraph="500000"/>
    </behavior>
 </endpointBehaviors>

但我收到的错误如下:"Invalid element in configuration. The extension name 'dataContractJsonSerializer' is not registered in the collection at system.serviceModel/extensions/behaviorExtensions."

将行为更改为<dataContractSerializer maxItemsInObjectGraph="500000"/>不会产生任何错误但不会更改该值(因为我没有使用dataContractSerializer,这并不奇怪)

使用ChannelFactory创建客户端,因此我无法使用此处所述的ServiceBehavior属性here

1 个答案:

答案 0 :(得分:2)

我不知道你是否可以通过config(还没试过)来做,但你可以在代码上增加MaxItemsInObjectGraph属性,它应该可以工作。在下面的示例中,如果我不增加它,则调用失败;否则就会成功。

public class StackOverflow_5867304_751090
{
    public class Product
    {
        public string Name { get; set; }
        public int Price { get; set; }
    }
    [ServiceContract]
    public interface ITest
    {
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        List<Product> GetProducts(int size);
    }
    public class Service : ITest
    {
        public List<Product> GetProducts(int size)
        {
            List<Product> result = new List<Product>();
            for (int i = 0; i < size; i++)
            {
                result.Add(new Product { Name = "Prod " + i, Price = i });
            }
            return result;
        }
    }
    static Binding GetBinding()
    {
        return new WebHttpBinding() { MaxReceivedMessageSize = int.MaxValue };
    }
    static void AddBehavior(ServiceEndpoint endpoint)
    {
        endpoint.Behaviors.Add(new WebHttpBehavior());
        foreach (var operation in endpoint.Contract.Operations)
        {
            DataContractSerializerOperationBehavior dcsob = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
            if (dcsob != null)
            {
                dcsob.MaxItemsInObjectGraph = 1000000;
            }
        }
    }
    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(), "");
        AddBehavior(endpoint);
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
        AddBehavior(factory.Endpoint);
        ITest proxy = factory.CreateChannel();
        Console.WriteLine(proxy.GetProducts(100000).Count);

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}