Как загрузить большие (> 25 МБ) файлы в веб-сервис? - PullRequest
29 голосов
/ 16 июня 2009

У меня есть веб-сервис, который берет байт [] и сохраняет его.

Это прекрасно работает для «маленьких» файлов, но как только я достиг определенного размера, веб-служба не работает и возвращает «Запрос не выполнен с состоянием HTTP 404: Не найдено».

Из того, что я видел, похоже, что параметр IIS ограничивает размер файла, который можно публиковать (чтобы предотвратить атаки типа «отказ в обслуживании»). Я пытался увеличить этот параметр, но у меня возникают проблемы с определением, какой параметр и где / как можно установить. Я использую IIS7, и веб-сервис выполняется в .net (asmx).

В web.config веб-службы я добавил следующее (что, казалось, увеличивало размер файла, который может быть принят, но не полностью до этого размера настройки)

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

Любые предложения о том, где (и как) увеличить размер файла, чтобы веб-служба была бы высоко оценена.

Ответы [ 8 ]

31 голосов
/ 01 июля 2009

В дополнение к httpRuntime / maxRequestLength, упомянутому в вопросе, похоже, есть дополнительный элемент, который можно добавить в файл web.config веб-службы, чтобы разрешить передачу больших файлов.

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

Похоже, что для загрузки файлов большего размера через веб-сервисы.

5 голосов
/ 19 октября 2010

Просто чтобы добавить информацию людям, которые ищут этот web.config:

C: \ Program Files \ Common Files \ Microsoft Shared \ Расширения веб-сервера \ 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 голосов
/ 16 июня 2009

Если бы я застрял при необходимости использовать веб-службы и нуждался в поддержке очень больших файлов, я бы посмотрел на реализацию системы, которая позволяет загружать файлы по частям.

Например.

  • ticketId GetTicket (размер)
  • UploadData (ticketId, byte [] payload) (может вызываться столько раз, сколько вы хотите)
  • FinalizeUpload (ticketId)

Это позволит вам группировать большие загрузки и не хранить слишком много данных в памяти. Недостатком является то, что вы все еще используете довольно неэффективный транспортный механизм.

5 голосов
/ 16 июня 2009

Следует помнить, что веб-сервисы изначально не предназначены для передачи файлов. Любой специально разработанный протокол передачи файлов, вероятно, будет работать лучше, чем веб-сервис. Например, такие протоколы с большей вероятностью будут иметь дело с исправлением ошибок, частичной загрузкой и т. Д.

Однако, если вы собираетесь использовать веб-службы для этой цели в .NET, вы должны использовать WCF, если это вообще возможно. Помимо прочих преимуществ, WCF поддерживает потоковую передачу и поэтому будет намного более эффективным с точки зрения использования памяти. Я обеспокоен тем, что если вы последуете двум (точным) предложениям, приведенным выше, ваш следующий результат будет исключением «нехватка памяти или ресурсов», поскольку старая технология ASMX пытается загрузить весь файл размером 25 МБ в память сразу. Фактически, он может иметь несколько копий в памяти одновременно!

4 голосов
/ 16 июня 2009

Если вы настроены на использование веб-служб для перемещения по файлам, я бы по крайней мере рассмотрел возможность использования вложений WS-Attachment / DIME. Основная проблема при отправке byte [] через веб-сервисы заключается в том, что они помещаются в тело SOAP, которое кодируется в виде базовой строки 64. Кодирование файлов, подобных этому , увеличивает размер файла на две трети в мыльном теле (т. Е. Файл размером 6 МБ становится файлом 9 МБ по сети).

Вероятно, ваша загрузка 25 МБ превращается в ОГРОМНЫЕ мыльные конверты.

Я бы настоятельно рекомендовал прочитать это. Что может привести вас в DIME.

Вот выдержка.

Microsoft WSE Toolkit позволяет большой вложения для отправки вместе с Метод веб-службы с использованием DIME и Стандарты WS-Attachments. Что ж изучить эти стандарты и почему они более эффективны, чем большие количество двоичных данных в сети сервисный звонок через другие общие значит.

Надеюсь, это поможет!

1 голос
/ 16 июня 2009

Это не дает конкретного ответа на ваш вопрос, но в прошлом я использовал WCF для передачи имен файлов / путей / списков, а затем использовал библиотеку FTP для передачи файлов по FTP.

1 голос
/ 16 июня 2009

maxRequestLength в килобайтах, а не в байтах. Это должно дать вам ограничение в 30 МБ в течение 4-минутного периода ожидания.

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

Наличие слишком больших чисел может фактически помешать применению ваших значений. Я думаю Я столкнулся с этим несколько лет назад, когда подумал, что это ограничение в байтах (смутная память).

0 голосов
/ 14 ноября 2011

это сработало для меня:

            <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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...