it-swarm.com.ru

Как я могу отправить файл через REST API?

Я пытаюсь отправить файл на сервер через API REST. Файл может быть любого типа, хотя его размер и тип может быть ограничен вещами, которые можно отправлять в виде вложений электронной почты. 

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

Для ясности я контролирую как клиентский, так и серверный код, поэтому я не ограничен каким-либо конкретным подходом. 

5
Kevin Wells

Я бы порекомендовал вам заглянуть в RestSharp
http://restsharp.org/

В библиотеке RestSharp есть методы для отправки файлов в службу REST. (RestRequst.AddFile()). Я полагаю, что на стороне сервера это преобразуется в закодированную строку в теле, а тип содержимого в заголовке указывает тип файла. 

Я также видел, как это делается путем преобразования потока в строку base-64 и передачи его в качестве одного из свойств сериализованного объекта json/xml. Особенно, если вы можете установить ограничения по размеру и хотите включить метаданные файла в запрос как часть одного и того же объекта, это работает очень хорошо.

Это действительно зависит от размера ваших файлов. Если они очень большие, вам нужно рассмотреть потоковую передачу, нюансы которой подробно рассмотрены в этом SO посте: Как потоковые ресурсы вписываются в парадигму RESTful?

5
MutantNinjaCodeMonkey

Основываясь на предложении @ MutantNinjaCodeMonkey о RestSharp. Мой пример использования заключался в публикации webform данных из метода $.ajax в jquery в контроллер web api. Служба API restful требует, чтобы загруженный файл был добавлен в тело запроса. Упомянутый выше метод restsharp по умолчанию для AddFile вызвал ошибку The request was aborted: The request was canceled. Сработала следующая инициализация:

// Stream comes from web api's HttpPostedFile.InputStream 
     (HttpContext.Current.Request.Files["fileUploadNameFromAjaxData"].InputStream)
using (var ms = new MemoryStream())
{
    fileUploadStream.CopyTo(ms);
    photoBytes = ms.ToArray();
}

var request = new RestRequest(Method.PUT)
{
    AlwaysMultipartFormData = true,
    Files = { FileParameter.Create("file", photoBytes, "file") }
};
1
Ben Sewards
  1. Определите файл (ы), транспортируемый с запросом.
  2. Определите путь для загрузки файла (и убедитесь, что CHMOD 777 существует для этого каталога)
  3. Принять клиент подключиться
  4. Используйте готовую библиотеку для фактической загрузки

Просмотрите следующее обсуждение: REST загрузка файла с помощью HttpRequestMessage или Stream?

0
Daniel Golub

Вы можете отправить его как POST запрос на сервер, передав файл в виде FormParam.

    @POST
        @Path("/upload")
       //@Consumes(MediaType.MULTIPART_FORM_DATA)
        @Consumes("application/x-www-form-urlencoded")
        public Response uploadFile( @FormParam("uploadFile") String script,  @HeaderParam("X-Auth-Token") String STtoken, @Context HttpHeaders hh) {

            // local variables
            String uploadFilePath = null;
            InputStream fileInputStream = new ByteArrayInputStream(script.getBytes(StandardCharsets.UTF_8));

            //System.out.println(script); //debugging

            try {
                  uploadFilePath = writeToFileServer(fileInputStream, SCRIPT_FILENAME);
            }
            catch(IOException ioe){
               ioe.printStackTrace();
            }
            return Response.ok("File successfully uploaded at " + uploadFilePath + "\n").build();
        }

 private String writeToFileServer(InputStream inputStream, String fileName) throws IOException {

        OutputStream outputStream = null;
        String qualifiedUploadFilePath = SIMULATION_RESULTS_PATH + fileName;

        try {
            outputStream = new FileOutputStream(new File(qualifiedUploadFilePath));
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
            outputStream.flush();
        }
        catch (IOException ioe) {
            ioe.printStackTrace();
        }
        finally{
            //release resource, if any
            outputStream.close();
        }
        return qualifiedUploadFilePath;
    }
0
Erick