【问题标题】:How do I upload large (> 25MB) files to a web service?如何将大 (> 25MB) 文件上传到 Web 服务?
【发布时间】:2010-11-03 04:35:36
【问题描述】:

我有一个网络服务,它接受一个字节[]并保存它。

这适用于“小”文件,但一旦达到一定大小,Web 服务就会失败并返回“请求失败,HTTP 状态 404:未找到。”

据我所知,这似乎是一个 IIS 设置,它限制了可以发布的文件的大小(以防止拒绝服务攻击)。我试图增加该设置,但我无法确定设置什么以及在哪里/如何设置它。我正在使用 IIS7,并且 web 服务是在 .net (asmx) 中完成的。

在 web 服务的 web.config 中,我添加了以下内容(这似乎增加了可以接受的文件大小,但不是一直到这个设置大小)

  <system.web>
     <httpRuntime executionTimeout="999999" maxRequestLength="2097151" />
     ...
  </system.web>

任何关于在何处(以及如何)增加 Web 服务文件大小的建议将不胜感激。

【问题讨论】:

  • 关于 WCF/FTP/WS-Attachment/DIME:很好的建议和一些有趣的阅读。这些可能是我最终将使用的长期解决方案类型。但是,如果有一些短期解决方案可以更改 IIS7 中的上传大小,那就太好了。谢谢。

标签: .net web-services iis-7 large-file-upload


【解决方案1】:

除了问题中提到的 httpRuntime/maxRequestLength 之外,似乎还有一个附加项可以添加到 Web 服务的 web.config 文件中以允许大文件传输。

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

这似乎可以通过网络服务上传更大的文件。

【讨论】:

  • 请注意:当您从 WCF 服务获得 404 但在 WCF 跟踪中没有错误消息时,表明您缺少此设置(是的,我知道非常有帮助 - 谢谢WCF)。很高兴你找到了这个 Chris,你让我在这上面浪费了更多的时间。
  • 是的,今天这个“额外”设置浪费了我一天中的许多小时。我没有意识到,使用 IIS7,您需要在 web.config 的两个位置引用最大的文件大小。但是,是的,有了这个 maxAllowedContentLength 设置,我终于可以上传 31Mb 的文件了。
  • @AndyBritcliffe “感谢 WCF”。在我看来,在这种情况下 404 源自 IIS 本身,因此 WCF 可能甚至没有听说过该事件,因此几乎没有机会记录任何有关它的内容。改写为“感谢微软”,批评仍然存在。 :)
  • 又一票感谢,这已经让我头疼了 小时
【解决方案2】:

您应该记住,Web 服务主要不是作为文件传输机制设计的。任何专门设计的文件传输协议都可能比 Web 服务做得更好。例如,此类协议更有可能处理错误恢复、部分上传等问题。

但是,如果您打算在 .NET 中为此目的使用 Web 服务,则应尽可能使用 WCF。除了其他好处之外,WCF 处理流式传输,因此在内存使用方面效率更高。我担心如果您遵循上面的两个(准确)建议,您的下一个结果将是“内存或资源不足”异常,因为旧的 ASMX 技术试图一次将整个 25MB 文件加载到内存中。事实上,它可能同时在内存中有多个副本!

【讨论】:

    【解决方案3】:

    如果我不得不使用 Web 服务并且需要支持非常大的文件,我会考虑实施一个允许您分段上传文件的系统。

    例如。

    • ticketId GetTicket(大小)
    • UploadData(ticketId, byte[] payload)(这个可以调用多次)
    • FinalizeUpload(ticketId)

    这将允许您将大量上传内容分块,而不会在内存中保存太多数据。缺点是您仍在使用效率相当低的传输机制。

    【讨论】:

    • 这应该是公认的解决方案,因为它占用的内存更少,甚至可以支持并行性。
    【解决方案4】:

    只是向搜索此 web.config 的人添加信息:

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI

    <location path="Copy.asmx"> <!-- Name of you asmx -->
        <system.webServer>
          <security>
            <requestFiltering>
              <requestLimits maxAllowedContentLength="104857600"/> <!-- 100 megs -->
            </requestFiltering>
          </security>
        </system.webServer>
      </location>
    

    在解决此问题相当长的一段时间后,这解决了我们的问题。

    【讨论】:

      【解决方案5】:

      如果您打算使用 Web 服务来移动文件,我至少会考虑使用 WS-Attachment / DIME 附件。通过 Web 服务发送 byte[] 的主要问题是它们被放入 SOAP 主体中,该主体被编码为 base 64 字符串。像这样对文件进行编码文件大小在soap主体中增加了三分之二(即,6 MB 的文件通过网络变成了 9 MB 的文件)。

      您上传的 25 MB 文件可能会变成巨大的肥皂信封。

      我强烈建议 reading this. 这可能会让你进入 DIME。

      这是一段摘录。

      Microsoft 的 WSE 工具包允许大型 附件一起发送 使用 DIME 的 Web 服务方法和 WS-附件标准。好吧 检查这些标准及其原因 比发送大数据更有效率 Web 中的二进制数据量 通过其他常见的服务调用 意思。

      希望有帮助!

      【讨论】:

      • 正是我要建议的。 XML 拒绝服务过滤器将缓冲整个 SOAP 消息,并且缓冲区大小是有限的。将 base-64 编码的二进制文件作为附件发送可以避免这种情况。 DIME 将使 Java、PHP 和其他客户端也更容易使用该服务。
      • 抱歉,WSE 已过时。除非您没有其他选择,否则不要使用它。很抱歉,但似乎不是每个人都听说过这一点,或者不是所有人都知道 Visual Studio 2008 或更高版本不支持 WSE。
      • John 提出了一个很好的观点,WSE 已被弃用,与 WCF 相比,它的路线图相当黯淡。话虽这么说,如果我们谈论的是对现有 Web 服务的更新,而该服务不会大修到 WCF(或 .NET v3.0+ 框架不可行),我会坚持我的观点并推荐 DIME /WS-附件。
      • @Tyler:你可能想在这里查看我的个人资料,看看这是否能让事情更清楚。 WSE 的正确用词不是“已弃用”,而是“已过时”。与“已弃用”可能暗示的相比,它更接近于实际上不受支持。确实,WSE 的正确答案是“不要去那里”。见social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/…
      • 这在搜索了 2 小时后救了我,如果您的文件限制为 10 mgb,您需要对网络服务设置更大的限制。谢谢
      【解决方案6】:

      maxRequestLength 以 KB 为单位,而不是字节。这应该会在 4 分钟的超时窗口内为您提供 30 MB 的限制。

      <httpRuntime executionTimeout="240" maxRequestLength="30000" />
      

      数字过高实际上可能会阻止您的值被应用。我认为几年前我遇到了这个问题,当时我认为这是一个字节限制(模糊的内存)。

      【讨论】:

      • 我更改为这些值,结果相同。我从这篇(有些相关/有些不相关)文章中获取的值:support.microsoft.com/kb/925083 - 两个值集似乎都有相同的问题。
      • 接收页面上的 ScriptTimeout 设置为多少?
      【解决方案7】:

      这并没有具体回答您的问题,但我过去所做的是使用 WCF 传输文件名/路径/列表,然后使用 FTP 库通过 FTP 传输文件。

      【讨论】:

        【解决方案8】:

        这对我有用:

                    <binding name="uploadFilesBasicHttpBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" receiveTimeout="00:10:10" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00">
                        <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
                        <security mode="TransportWithMessageCredential">
                            <message clientCredentialType="UserName"/>
                        </security>
                    </binding>
        
        猜你喜欢
        • 1970-01-01
        • 2012-09-16
        • 2014-05-30
        • 2017-07-28
        • 1970-01-01
        • 2012-05-20
        • 1970-01-01
        • 2011-11-16
        • 2015-03-17
        相关资源
        最近更新 更多