Лучший способ получить файл через веб-сервис - PullRequest
4 голосов
/ 22 октября 2008

У меня есть API, состоящий из веб-сервисов ASP.NET, вызываемых через GET / POST / SOAP.

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

API должен быть как можно более легким в использовании. Я думаю об отказе от поддержки SOAP, так как наши клиенты PHP в основном используют методы GET / POST, а клиенты .NET не возражают против этого. Исходя из этого, я думаю просто создать метод UploadFile (fileName) и требовать, чтобы пользователь отправлял файл через POST как обычную загрузку файла.

Однако я не смогу указать поле файла в качестве параметра метода, верно? Так что, если я просто укажу в документации «файл должен быть отправлен в поле POST под названием« Файл »», это создаст какие-либо проблемы, когда мне нужно будет прочитать файл?

Все файлы в двоичном формате, PDF, различные форматы изображений, FLV и так далее. Кроме того, размеры файлов в основном будут находиться в пределах 2-20 МБ, но, учитывая приведенное выше решение, возникнут ли у меня проблемы с приемом файлов в области 250 МБ?

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


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

Ответы [ 4 ]

2 голосов
/ 22 октября 2008

Нет ничего ужасного в том, что у вас есть простой метод POST для отправки файла, только детали привязки загрузки файла к любым соответствующим метаданным (т. Е. Другим параметрам метода, если он был связан с методом).

Сегодня я считаю, что способ обработки больших объектов в вызовах SOAP - это MTOM. Это оптимизация, но она предоставляет вам потоковый интерфейс для фактических полезных нагрузок. Таким образом, фреймворк может при необходимости легко кэшировать большой объект на диск (действительно ли они это делают - это другой вопрос, но никто не хочет поглощать загрузку 250 Мб в память, поэтому я полагаю, что любой современный объект разгрузит большие вложения) .

2 голосов
/ 22 октября 2008

"не создаст ли это проблемы, когда мне нужно будет прочитать файл?" Нет проблем. Когда вы обрабатываете запрос POST, у вас есть MIME-вложение к POST, которое является файлом. Прочитать этот файл относительно просто.

"Будут ли у меня проблемы с приемом файлов в области 250 МБ?" Нет. За исключением того, что для передачи больших файлов требуется некоторое время.

«Получение файла таким образом приведет к полной загрузке файла в память». Не обязательно верно. Многие веб-серверы обрабатывают запрос вплоть до вложения MIME и останавливают чтение, делая заголовки HTTP, запрос и открытый сокет доступными для дальнейшей обработки. Я не знаю про ASP, но знаю, что почти все фреймворки избегают чтения данных. Фреймворк оставляет это для вашего приложения.

Следовательно, вы можете читать данные порциями и записывать (или обрабатывать) эти порции, не считывая все это в память.

POST именно так и делается. Существует не так много альтернатив, не выходящих за пределы узкого пространства веб-сервисов HTTP. Конечно, вы можете использовать другие протоколы, такие как FTP (TFTP, SFTP) для перемещения файлов, но это часто сбивает с толку людей, пишущих клиентские приложения.

При желании вы можете предоставить клиентскую библиотеку, которая создает объект HttpWebRequest с методом POST, и поток с вложением. Но вы не сильно экономите, так как класс HttpWebRequest выглядит довольно просто. Вот пример кода .

1 голос
/ 22 октября 2008

Однако я не смогу указать поле файла в качестве параметра метода, верно? Так что, если я просто укажу в документации «файл должен быть отправлен в поле POST с именем« Файл »», это создаст какие-либо проблемы, когда мне нужно будет прочитать файл?

Нет причин, по которым вы не можете включить дополнительные параметры POST (или GET, в этом отношении). Я бы, вероятно, сам взял имя файла в качестве дополнительного параметра POST, чтобы клиенты, которые автоматически используют локальное имя файла в запросе, могли легко переименовываться. Если я ожидал конфликта имен, я мог бы даже вернуть выбранное имя сервера в случае конфликтов ... Я думаю, что REST люди используют какой-то код статуса HTTP Created для этого.

Все файлы в двоичном формате, PDF, различные форматы изображений, FLV и так далее. Кроме того, размеры файлов в основном будут в пределах 2-20 МБ, но, учитывая приведенное выше решение, возникнут ли у меня проблемы с приемом файлов в области 250 МБ?

Вам нужно настроить maxRequestLengths и executeTimeouts в web.config. И, если кто-то попытается загрузить 250 МБ по коммутируемому соединению, давайте просто скажем, что это, вероятно, не сработает.

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

ASP.NET 2.0+ помещает загруженные файлы на диск по мере их поступления, чтобы избежать предварительной загрузки всего запроса в ОЗУ. Откорректируйте requestLengthDiskThreshold web.config, в зависимости от ситуации, чтобы сбалансировать скорость и использование памяти. Вы не могли бы взять поток, если бы захотели ... хотя вы можете взять массив byte []. Я действительно не уверен, что это будет означать, хотя ....

Для небольших файлов вы можете сделать base 64, что должно быть тривиально для клиентов. Но для 20 МБ накладные расходы не стоили бы.

Существует множество различных компонентов для загрузки файлов ASP.NET, которые в основном подключаются к Begin_Request в виде HttpModule и перехватывают поток запросов для любых мультипартий / форм-загрузок. В ASP.NET 2.0 это, вероятно, не нужно, если только вы не хотите предоставить какой-то обратный вызов прогресса или что-то в этом роде. Если это так - механика их должна работать с веб-сервисом так же.

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

Единственный вопросительный знак, который у меня возник бы, это уровень поддержки multipart / form-data в библиотеках http ваших клиентов. Я подозреваю, что это довольно хорошо, но вы можете проверить.

0 голосов
/ 22 октября 2008

Не прямой ответ, но вы также можете посмотреть БИТЫ - Фоновая интеллектуальная служба передачи [wiki]

Может относиться или не относиться к вам / вашим клиентам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...