2

I have a WCF service method I've implemented that gets passed an IEnumerable

    [OperationContract]
    List<Item> GetItems(DateTime sinceDate, IEnumerable<Guid> idList);

The method works as intended when passing in an IEnumerable of size 1000 or fewer; the service returns with an expected response. At some point, the array passed in is too large (seen at 2000 items) and a System.ServiceModel.ProtocolException is thrown, "{"The remote server returned an unexpected response: (400) Bad Request."}"

I'm not sure what's governing the array size limitation. I'm aware of the readerQuotas section of a binding, and the maxArrayLength is set to the default 16384. My buffer sizes are set large enough, but I'm not sure why the service call is failing. Is there a limitation on the basicHttpBinding for array sizes passed in? What needs to change in my configuration so that I can pass in large arrays?

Here is my app.config in the client side. Server side is equivilant.

<binding name="BasicHttpBinding_IMyService" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="20000000" maxBufferPoolSize="524288" maxReceivedMessageSize="20000000"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                  realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
</binding>
Stealth Rabbi
  • 10,156
  • 22
  • 100
  • 176
  • Have you tried to increase the timeout options as well to allow the transport of all that data ? Look here http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpbinding.aspx – CheGueVerra Mar 06 '12 at 13:35
  • Have you set the maxItemsInObjectGraph property as said below? Also set the values in your readerQuotas to large values. Make sure they are set both on client and server side as well – Rajesh Mar 06 '12 at 13:44

1 Answers1

0

You need to register a service behavior that increase the max object items in graph:

<serviceBehaviors>
    <behavior name="IncreadedSizeBehavior">
      <dataContractSerializer maxItemsInObjectGraph="100000"/>
    </behavior>
  </serviceBehaviors>

You then need to register this behavior in your endpoint:

<services>
    <service name="MyService" behaviorConfiguration="IncreadedSizeBehavior">
        <host />
        <endpoint />
</services>

The thing that is most helpful when debugging wcf issues is enabled trace error logging:

<system.diagnostics>
        <trace autoflush="true" />
        <sources>
            <source name="System.ServiceModel"
                            switchValue="Error"
                            propagateActivity="true">
                <listeners>
                    <add name="sdt"
                            type="System.Diagnostics.XmlWriterTraceListener"
                            initializeData= "ErrorTrace.svclog"
                            />
                </listeners>
            </source>
        </sources>
    </system.diagnostics>

Then opening that trace file with the svc trace viewer, downloadable with the windows sdk. You get a nice view of all the errors and what the actual error was when the message was being processed.

Oved D
  • 7,132
  • 10
  • 47
  • 69
  • Thanks. With the logging enabled, the error indicates that it's an issue with the maximum incoming messages: The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element. – Stealth Rabbi Mar 06 '12 at 13:52
  • Looking at your sample, don't you have that set to 20000000? – Oved D Mar 06 '12 at 14:15
  • 1
    Oh actually your example is from the client side, I'd imagine you have to set it on the server side as well. – Oved D Mar 06 '12 at 14:16
  • 1
    Yeah, I had to set MaxReceivedMessageSize on the server side app.config. Setting maxItemsInObjectGraph was unnecessary, but your answer and comments certainly got me to where I needed to be. thanks. – Stealth Rabbi Mar 06 '12 at 14:59
  • So it's not that both the client and server had to match, but simply that the size that the service was receiving (sent from a client) was larger than the default? – Stealth Rabbi Mar 06 '12 at 15:05
  • Yeah I would think so. I msft puts a default value as a security measure to prevent the service from getting overloaded by a massive request. – Oved D Mar 06 '12 at 15:22