1

I'm quite new to WCF services, and I just ran into this known issue, when the uploaded file is too big to upload. My situation is strange because I set both maxAllowedContentLength and maxRequestLength to a high number, so it should have no problems with uploading 300 MB files... With small files it works perfectly, so for me it seems like it just forgets about my settings. I tried so many ideas to solve this problem, so maybe I messed up things in my config file, there may be some unnecessary parts, but still I couldn't find the solution.

I'm working with IIS 10 and .Net 4.5.

My WCF Service configuration:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="4048576" requestLengthDiskThreshold="4048576" executionTimeout="3600" />
</system.web>
<system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior name="TileServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    <behavior name="FileUploadServiceBehavior">
      <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<protocolMapping>
  <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ITileService" sendTimeout="01:00:00" maxBufferSize="5000000" /> 
    <binding name="HttpBinding_MTOM" 
              messageEncoding="Text" 
              transferMode="Streamed" 
              maxReceivedMessageSize="4294967294" 
              maxBufferSize="65536" 
              maxBufferPoolSize="65536" />
    <binding name="BasicHttpBinding_ITileServiceUpload" 
                closeTimeout="00:01:00" 
                openTimeout="00:01:00" 
                receiveTimeout="00:10:00" 
                sendTimeout="00:10:00" 
                allowCookies="false" 
                bypassProxyOnLocal="false" 
                hostNameComparisonMode="StrongWildcard" 
                maxBufferSize="65536" 
                maxBufferPoolSize="524288" 
                maxReceivedMessageSize="4294967294" 
                messageEncoding="Text" 
                textEncoding="utf-8" 
                transferMode="Streamed" 
                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>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost/AEGIS.TileService/TileService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITileServiceUpload" contract="AEGIS.TileService.ITileService" name="BasicHttpBinding_ITileServiceUpload" />
</client>
<services>
  <service behaviorConfiguration="FileUploadServiceBehavior" name="AEGIS.TileService.TileService">
    <endpoint address="winceStream" binding="basicHttpBinding" bindingConfiguration="HttpBinding_MTOM" contract="AEGIS.TileService.ITileService" />
  </service>
</services>
</system.serviceModel>
  <system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="4294967295" maxUrl="4294967295" maxQueryString="4294967295" />
  </requestFiltering>
</security>

The web.config file from my ASP.NET web app, where the service is referenced.

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ITileService"/>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost/AEGIS.TileService/TileService.svc/winceStream" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITileService" contract="TileService.ITileService" name="BasicHttpBinding_ITileService"/>
</client>

My upload method is implemented like this:

public void UploadFile(FileUploadMessage request)
    {
        string basePath = AppDomain.CurrentDomain.BaseDirectory + @"\Images\";
        string serverFileName = Path.Combine(basePath, request.Filename);

        using (FileStream outfile = new FileStream(serverFileName, FileMode.Create))
        {
            const int bufferSize = 65536; // 64K
            Byte[] buffer = new Byte[bufferSize];
            int bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize);
            while (bytesRead > 0)
            {
                outfile.Write(buffer, 0, bytesRead);
                bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize);
            }
        }
    }

Where FileUploadMessage is like this:

[MessageContract]
public class FileUploadMessage
{
    [MessageHeader(MustUnderstand = true)]
    public string Filename;
    [MessageBodyMember(Order = 1)]
    public Stream FileByteStream;
}

EDIT 1:

http://ipswitchft.force.com/kb/articles/FAQ/Unable-to-transfer-files-over-30MB-with-the-Web-Transfer-Module-or-Ad-Hoc-Transfer-Module-1307565986108

I found this article about this issue. Maybe my problem is not with the WCF service or config, but with IIS?

I set the requestLimits of the Default App Pool also to 1000000000. The error still appears.

Also in Option 3 the article writes about changing the ApplicationHost.config. The strange thing is that I don't have anything in that file about requestLimits. Maybe that's the main problem?

  • Make sure you have installed IIS request filtering module. Or try to reinstall it. (Go to Add remove windows features -> World Wide Web Services -> Security -> Request Filtering). This will add the module and it should update the applicationhost file. – Dhanuka777 Nov 24 '15 at 00:10

2 Answers2

1

Your are probably dealing with multiple "issues".

Remember to configure your Server AND Client accordingly!

First, i would configure my .NET runtime (WCF) and IIS behavior https://stackoverflow.com/a/6472631/1498669

NOTE: maxRequestLength is in KILOBYTES whereas maxAllowedContentLength is in BYTES


I would:


  1. set the default IIS parameter for your specific application (not for the whole machine!) using web.config in your base webfolder to a 'relatively' high value
<system.webServer>
 <security>
  <requestFiltering>

   <!-- maxAllowedContentLength defaults to 30000000 BYTES = 30MB --> 
   <!-- i use 100MB (100 *1024*1024)-->

   <requestLimits maxAllowedContentLength="104857600" /> 
  </requestFiltering> 
 </security>
</system.webServer>

  1. set the .NET Framework parameter to my expected 'max' value (at least a bit lower than the iis value) in KB to be able to catch the exception before iis presents me a error website (note: also raise the timeout for big data to transfer).
<system.web>

 <!-- maxRequestLength defaults to 4096 KILOBYTES = 4MB -->
 <!-- i use 80MB (80 *1024) -->
 <!-- please notes that if you use base64 encoded messages -->
 <!-- you have to calculate the overhead with CEIL(nBytes/3)*4 -->
 <!-- executionTimeout defaults to 110 SECONDS, i use 5 minutes -->

 <httpRuntime maxRequestLength="81920" executionTimeout="600" /> 
</system.web>

  1. after that, i configure my endpoints and their bindings

https://msdn.microsoft.com/en-us/library/ms733865.aspx

Also see https://stackoverflow.com/a/36931852/1498669 for the different attributes and their meaning.


As reference, the machine web.configs are located in (depending if you are using 2.0/4.0 and 32/64bits):

  • 32bit / net2.0-3.5
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\Config\web.config
  • 32bit / net4.x
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config
  • 64bit / net2.0-3.5
    C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Config\web.config
  • 64bit / net4.x - this mostly gets used in Server2008R2 and higher
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config

in these directories there are also:

  • web.config.default - you can copy that over web.config to reset your machine config, if you unintentionally altered the machine config!
  • web.config.comments - for a specific explanation of the attrs/elements

If you want to get in touch to all available elements/attributes - consult your visual studio installation directory, e.g:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\Xml\Schemas\DotNetConfig45.xsd


Offtopic: as additional info to your security settings, see https://msdn.microsoft.com/en-us/library/ff648505.aspx

Bernhard
  • 2,541
  • 1
  • 26
  • 24
0

You need to make similar changes to Web config as well.

You are using "BasicHttpBinding_ITileService" in the web. Therefore in the WCF config and Web config file needs to have similar configuration.

<binding name="BasicHttpBinding_ITileService" 
          maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
          maxReceivedMessageSize="2147483647">
         <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
               maxArrayLength="2147483647" maxBytesPerRead="2147483647" 
               maxNameTableCharCount="2147483647" />
     </binding>
Dhanuka777
  • 8,331
  • 7
  • 70
  • 126
  • Thanks for your comment, I replaced that binding in my wcf service web.config, but unfortunately it didn't solve my problem. :( I just tested out, the current limit is around 30 MB. – grp zeneszerzo Nov 23 '15 at 22:32
  • Do you have the same settings for "BasicHttpBinding_ITileService" binding in web and wcf (client and server)? – Dhanuka777 Nov 23 '15 at 23:22
  • Yes, I copy-pasted your code to the web.config of my asp.net project and to the web.config of my wcf service project. Please check the edit what I made on my question, maybe you see something I don't see. – grp zeneszerzo Nov 23 '15 at 23:35
  • Are you running both the website and WCF under the Default app pool? or do they have separate app pools? Can you provide more details about the error. Also, when you upload a large file, does it hits the webserver? Is the issue is with web-wcf communication? – Dhanuka777 Nov 24 '15 at 00:01
  • The wcf service is under the Default App Pool. The asp.net webpage is in debug from Visual Studio 2015 Community. – grp zeneszerzo Nov 24 '15 at 00:04
  • When you upload a large file, does it hits the web server without any error? – Dhanuka777 Nov 24 '15 at 00:18