1

我对 WCF 服务很陌生,当上传的文件太大而无法上传时,我刚刚遇到了这个已知问题。我的情况很奇怪,因为我将maxAllowedContentLengthmaxRequestLength都设置为一个很高的数字,所以上传 300 MB 文件应该没有问题......对于小文件,它可以完美运行,所以对我来说,它似乎只是忘记了我的设置。我尝试了很多想法来解决这个问题,所以也许我在我的配置文件中搞砸了,可能有一些不必要的部分,但我仍然找不到解决方案。

我正在使用 IIS 10 和 .Net 4.5。

我的 WCF 服务配置:

<?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>

我的 ASP.NET Web 应用程序中的 web.config 文件,其中引用了该服务。

<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>

我的上传方法是这样实现的:

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);
            }
        }
    }

FileUploadMessage 是这样的:

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

编辑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

我发现这篇关于这个问题的文章。也许我的问题不在于 WCF 服务或配置,而在于 IIS?

我将默认应用程序池的 requestLimits 也设置为 1000000000。错误仍然出现。

同样在选项 3 中,该文章还介绍了更改 ApplicationHost.config。奇怪的是,我在该文件中没有任何关于 requestLimits 的内容。也许这是主要问题?

4

2 回答 2

1

您可能正在处理多个“问题”。

请记住相应地配置您的服务器和客户端!

首先,我将配置我的 .NET 运行时 (WCF) 和 IIS 行为 https://stackoverflow.com/a/6472631/1498669

注意:maxRequestLength 以KILOBYTES为单位,而 maxAllowedContentLength 以BYTES为单位


我会:


  1. 使用基本 web 文件夹中的 web.config为您的特定应用程序(而不是整台机器!)设置默认 IIS 参数为“相对”高的值
<system.webServer>
 <security>
  <requestFiltering>

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

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

  1. 将 .NET Framework 参数设置为我预期的“最大值”值(至少比 iis 值低一点)(以 KB 为单位),以便能够在 iis 向我显示错误网站之前捕获异常(注意:也提高大数据的超时转让)。
<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. 之后,我配置我的端点及其绑定

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

另请参阅https://stackoverflow.com/a/36931852/1498669了解不同的属性及其含义。


作为参考,机器 web.configs 位于(取决于您是否使用 2.0/4.0 和 32/64 位):

  • 32位/net2.0-3.5
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\Config\web.config
  • 32位/net4.x
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config
  • 64位/net2.0-3.5
    C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Config\web.config
  • 64bit / net4.x - 这主要用于 Server2008R2 及更高版本
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config

在这些目录中还有:

  • web.config.defaultweb.config-如果您无意中更改了机器配置,您可以复制它以重置您的机器配置!
  • web.config.comments- 对于 attrs/elements 的具体解释

如果您想联系所有可用的元素/属性 - 请查阅您的 Visual Studio 安装目录,例如:

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


题外话:作为安全设置的附加信息,请参阅https://msdn.microsoft.com/en-us/library/ff648505.aspx

于 2016-12-13T10:02:13.497 回答
0

您还需要对 Web 配置进行类似的更改。

您正在网络中使用“BasicHttpBinding_ITileService”。因此在 WCF config 和 Web config 文件中需要有类似的配置。

<binding name="BasicHttpBinding_ITileService" 
          maxBufferSize="2147483647" maxBufferPoolSize="2147483647" 
          maxReceivedMessageSize="2147483647">
         <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
               maxArrayLength="2147483647" maxBytesPerRead="2147483647" 
               maxNameTableCharCount="2147483647" />
     </binding>
于 2015-11-23T22:24:28.940 回答