.net 如何将大 (> 25MB) 文件上传到 Web 服务?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/998927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:52:02  来源:igfitidea点击:

How do I upload large (> 25MB) files to a web service?

.netweb-servicesiis-7large-file-upload

提问by ChrisHDog

I have a web service that takes a byte[] and saves it.

我有一个 Web 服务,它需要一个字节 [] 并保存它。

This works fine for "small" files, but once I hit a certain size the web service fails and returns "The request failed with HTTP status 404: Not Found."

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

From what I've seen this appears to be an IIS setting that limits the size of a file that can be posted (to prevent Denial of Service attacks). I've tried to increase that setting, but I am having trouble determining what setting and where/how one would set it. I am using IIS7 and the webservice is done in .net (asmx).

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

In the web.config of the web service I have added the following (which seemed to increase the size of file that can be accepted, but not all the way to this setting size)

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

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

Any suggestions on where (and how) to increase the size of file that the web service would be greatly appreciated.

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

回答by ChrisHDog

In addition to the httpRuntime/maxRequestLength mentioned in the question, it looks like there is an additional item that can be added to the web service's web.config file to permit large file transfers.

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

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

This appears to enable larger files to be uploaded via web services.

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

回答by John Saunders

You should keep in mind that web services aren't primarily designed as file transfer mechanisms. Any purpose-designed file transfer protocol will likely do a better job than a web service. For instance, such protocols are more likely to deal with error recovery, partial uploads, etc.

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

However, if you're going to use web services for this purpose in .NET, you should use WCF, if at all possible. Among other benefits, WCF handles streaming, and will therefore be a lot more efficient in terms of memory usage. I'm concerned that if you follow the two (accurate) suggestions above, your next result will be "out of memory or resources" exceptions, as the old ASMX technology tries to load your entire 25MB file into memory at once. In fact, it may have several copies in memory at the same time!

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

回答by sonstabo

Just to add information to people googling this web.config:

只是为了向使用谷歌搜索这个 web.config 的人添加信息:

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

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>

This solved our problem after troubleshooting this issue for quite som time.

在对这个问题进行了很长时间的故障排除后,这解决了我们的问题。

回答by Sam Saffron

If I was stuck having to use web services and needed to support very large files I would look at implementing a system that allows you to upload files in pieces.

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

Eg.

例如。

  • ticketId GetTicket(size)
  • UploadData(ticketId, byte[] payload) (this can be called as many times as you want)
  • FinalizeUpload(ticketId)
  • ticketId GetTicket(size)
  • UploadData(ticketId, byte[] payload)(可以根据需要多次调用)
  • 完成上传(ticketId)

This would allow you to chunk up the big uploads, and not hold too much data in memory. The disadvantage is that you are still using a fairly inefficient transport mechanism.

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

回答by Tyler

If you're set on using Web Services to move around files I would at least consider using WS-Attachment / DIME attachments. The primary problem with sending byte[]'s over web services is that they get put in the SOAP body which is gets encoded as a base 64 string. Encoding files like this grows the size of the fileby as much as two thirds in the soap body (ie. a 6 MB file becomes a 9 MB file over the wire).

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

It's likely that your 25 MB upload is turning into HUGE soap envelopes.

您上传的 25 MB 很可能变成了巨大的肥皂封套。

I'd strongly suggest reading this.Which might get you into DIME.

我强烈建议阅读这篇文章。这可能会让你进入 DIME。

Here's an excerpt.

这是摘录。

Microsoft's WSE Toolkit allows large attachments to be sent along with a Web service method using the DIME and WS-Attachments standards. We'll examine these standards and why they are more efficient than sending large amounts of binary data in a Web service call through other common means.

Microsoft 的 WSE Toolkit 允许使用 DIME 和 WS-Attachments 标准将大型附件与 Web 服务方法一起发送。我们将研究这些标准以及为什么它们比通过其他常用方法在 Web 服务调用中发送大量二进制数据更有效。

Hope that helps!

希望有帮助!

回答by NotDan

This doesn't specifically answer you question, but what I've done in the past is use WCF to transfer file names/paths/listings, but then use an FTP library to transfer the file via FTP.

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

回答by richardtallent

maxRequestLength is in KB, not bytes. This should give you a 30 MB limit within a 4-minute timeout window.

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

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

Having numbers that are too high may be actually preventing your values from being applied. I thinkI ran into this a few years ago when I thought it was a byte limit (vague memory).

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

回答by Dragos Durlut

this worked for me:

这对我有用:

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