3

I have a VS 2010 solution containing a WCF service project and a unit test project. The unit test project has a service reference to the WCF service.

Web.config for the WCF service project sets a number of binding attributes to other-than-default values:

web.config: (Specifically note maxBufferSize="20000000")

<basicHttpBinding>
    <binding name="basicHttpBindingConfig" maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
      <readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Ntlm"/>
      </security>
    </binding>
</basicHttpBinding>

While examining this issue, I came to realize that the unit test project's service reference support files do not contain the values I would expect (i.e. the values configured in the WCF service's web.config):

configuration.svcinfo: (Specifically note maxBufferSize="65536")

  <binding hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" messageEncoding="Text" name="BasicHttpBinding_IBishopService" textEncoding="utf-8" transferMode="Buffered">
    <readerQuotas maxArrayLength="16384" maxBytesPerRead="4096" maxDepth="32" maxNameTableCharCount="16384" maxStringContentLength="8192" />
    <security mode="None">
      <message algorithmSuite="Default" clientCredentialType="UserName" />
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
    </security>
  </binding>

Deleting and re-creating the service reference or updating the service reference re-creates the files, but I still end up with the same values.

Why?

Update

Here's the app.config of the client

<binding name="BasicHttpBinding_IMyService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="200000000" maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000"
                        maxBytesPerRead="200000000" maxNameTableCharCount="200000000" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
Community
  • 1
  • 1
Eric J.
  • 147,927
  • 63
  • 340
  • 553

2 Answers2

0

That is correct behavior. Some information included in binding are specific to only one side of the configuration and both client and server can use completely different values. Also these values are defence against Denial of Service attach so service doesn't want to show them publicly.

Those values affects only processing of incoming messages so service configures how it will handle incoming requests and client configures how it will handle incoming responses. Requests and responses can have different characteristics and different configuration. There is no need for service to be configured to accept 1MB requests if it always receives only few KB requests and returns 1MB responses.

Btw. this is WCF specific feature not related to general web services and because of that there is no standardized way to describe this in WSDL.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • If this is correct behavior, what is the correct procedure to change those values? The default (?) values being applied do not work for my particular application (which is why I explored the settings to begin with). – Eric J. Sep 24 '11 at 14:47
  • You will modify values on client as you need. – Ladislav Mrnka Sep 24 '11 at 17:51
  • I had already modified the settings in app.config for the client, but these are also not reflected in the generated files, and I get an error related to a setting being too small. App.config added to question. – Eric J. Sep 25 '11 at 01:29
  • If your client is directly executable or web site / web application project you will have to set these values manually after each reference update. If a client is class library you can still maintain correct values in the main config of executalbe / web application. In this scenario you will have to manually synchronize other changes which are reflected by updating service reference. – Ladislav Mrnka Sep 25 '11 at 10:33
  • Update where? In the generated files? My app.config on the client side and web.config on the server side both have the desired values, only the generated support files have the wrong values. – Eric J. Sep 25 '11 at 21:33
  • What is generated support file? Only your real configs matter. – Ladislav Mrnka Sep 25 '11 at 21:53
  • I get a runtime exception when I try to send more than 64K over the wire. The exception is explicit about the configured size being 64K. Both my app.config on the client and web.config have increased the configuration well beyond that value. I'm struggling to understand where the runtime is pulling 64K from. – Eric J. Sep 26 '11 at 05:28
0

Same issue here and no solution after half a day messing about with config files... Changing automatically generated files is usually frowned upon, so my feeling says that "there has got to be a better way, Dennis".

UPDATE: I got my problem fixed by removing the name attribute in the binding configuration. So your current web.config is looking like this

<basicHttpBinding>
  <binding name="basicHttpBindingConfig" maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
    <readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Ntlm"/>
    </security>
  </binding>
</basicHttpBinding>

would become

<basicHttpBinding>
  <binding maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
    <readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Ntlm"/>
    </security>
  </binding>
</basicHttpBinding>

I think you only need to this at the client-side. By removing the name attribute, you essentially change the default basicHttpBinding configuration for your app, as far as I understand it. Credits for this solution here.

Another update: if you name your service configuration correctly (including the namespace) it will pick up the binding configuration. So instead of

<service name="ServiceName">

you need

<service name="My.Namespace.ServiceName">
Community
  • 1
  • 1
Sylvain Girard
  • 368
  • 3
  • 13
  • When I remove the `name` attribute from ` – Eric J. Oct 04 '11 at 06:27
  • If it complains that the named binding cannot be found, then it means it's picking it up and is effectively using that configuration. Are the client & server binding configurations the same now? Can you update your post with the service configurations for both? – Sylvain Girard Oct 07 '11 at 09:14