w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
WCF 4.5: An unexpected error occurred: The remote server returned an unexpected response: (413) Request Entity Too Large

Found my answer - I originally posted a link to it here, but one of the mods decided to delete the answer (thanks for that!), so I'll post the solution in its entirety instead:


In order to allow payloads (such as files or large arrays of data) OVER the default of 40KB to be sent to a WCF Service method, the changes required are predominantly in the web.config file of the WCF project. There is also one minor tweak required in the client's configuration, so we'll look at that first:

<configuration>
  ...
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <!-- Large Message Upload (Begin) -->
        <binding name="BasicHttpBinding_IUserService"
maxBufferPoolSize="2097152" maxReceivedMessageSize="2097152" />
        <!-- Large Message Upload (End) -->
        <binding name="BasicHttpBinding_ISystemService" />
        ...
      </basicHttpBinding>
    </bindings>
    ...
  </system.serviceModel>
</configuration>

When you first add a service reference to your client's project, Visual Studio automatically creates default binding and endpoint nodes in your config file. You'll need to add two new attributes to the binding node for your service: maxBufferPoolSize and maxReceivedMessageSize. Both attributes should have their values set to your desired file upload size limit IN BYTES. You'll also need to take note of the name for the next bit.

That's if for the client configuration, so on to the WCF Service. Here's an extract from mine:

<configuration>
   ...
  <system.serviceModel>

    <bindings>
      <basicHttpBinding>
        <!-- Large Message Upload (Begin) -->
        <binding name="BasicHttpBinding_IUserService"
                 maxBufferSize="2097152"
                 maxBufferPoolSize="2097152"
                 maxReceivedMessageSize="2097152"
                 closeTimeout="00:50:00" 
                 openTimeout="00:50:00" 
                 sendTimeout="00:50:00" 
                 receiveTimeout="00:50:00">
          <readerQuotas maxDepth="32" maxStringContentLength="100000"
                        maxArrayLength="2097152" maxBytesPerRead="4096"
                        maxNameTableCharCount="16384" />
          <security mode="None" />
        </binding>
        <!-- Large Message Upload (End) -->
      </basicHttpBinding>
    </bindings>

    <services>
      <!-- Large Message Upload (Begin) -->
      <service name="BlexEngine.Services.UserService"
               behaviorConfiguration="ServiceWithMetadata">
        <endpoint name="Default"
                  binding="basicHttpBinding"
                  bindingConfiguration="BasicHttpBinding_IUserService"
                  contract="BlexEngine.Services.IUserService" />
      </service>
      <!-- Large Message Upload (End) -->
    </services>

    <behaviors>
      <serviceBehaviors>
        <!-- Large Message Upload (Begin) -->
        <behavior name="ServiceWithMetadata">
          <!-- Large Message Upload (End) -->

          <!-- To avoid disclosing metadata information, set the values
below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"
/>
          <!-- To receive exception details in faults for debugging
purposes, set the value below to true.  
          Set to false before deployment to avoid disclosing exception
information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    ...
  </system.serviceModel>
  ...
</configuration>

As you can see there are three changes required:

1) Create a binding specifically for the service that you want to enable large file uploads for (my project publishes five services at the moment, but only one requires a larger file upload limit). Ensure that the value of the name attribute matches the name of the binding we noted in the client's web.config file. Copy the attributes and child nodes from the example above and modify as you see fit. All size values are, AKAIK, in bytes.

2) Jumping around a bit, we're going to move to the last change in the config extract next. Visual Studio creates a default behaviour node with all the correct settings, but does NOT set a name on that node, so add a name attribute and give it a value. ServiceWithMetadata was the value in the example I found, so that's what I used - I don't know if it really matters what you call it.

3) Create a service node for your service. The name must be the fully qualified name of your service class and the behaviourConfiguration needs to be the name of the service node, as set in step 2). Within the service node you'll need to configure an endpoint, the bindingConfiguration of which needs to be set to the name of the binding setup in step 1) and the contract of which needs to be set to the fully qualified name of the interface your service class adheres to.

That's it really. Figuring this out has taken far too long and I can't believe how complex the process has been or how little documentation there appears to be out there on this topic. To anyone suffering the same issue as I did: good luck! I hope that this post saves you the time I had to invest figuring this out the hard way.





© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.