简体   繁体   English

如何通过 REST API 发送文件?

[英]How can I send a File over a REST API?

I am trying to send a file to a server over a REST API.我正在尝试通过 REST API 将文件发送到服务器。 The file could potentially be of any type, though it can be limited in size and type to things that can be sent as email attachments.该文件可能是任何类型,但它的大小和类型可能会受到限制,可以作为 email 附件发送。

I think my approach will be to send the file as a binary stream, and then save that back into a file when it arrives at the server.我认为我的方法是将文件作为二进制 stream 发送,然后在到达服务器时将其保存回文件中。 Is there a built in way to do this in.Net or will I need to manually turn the file contents into a data stream and send that?是否有内置方法可以在.Net 中执行此操作,或者我是否需要手动将文件内容转换为数据 stream 并发送?

For clarity, I have control over both the client and server code, so I am not restricted to any particular approach.为清楚起见,我可以控制客户端和服务器代码,因此我不限于任何特定方法。

I'd recommend you look into RestSharp 我建议你看看RestSharp
http://restsharp.org/ http://restsharp.org/

The RestSharp library has methods for posting files to a REST service. RestSharp库具有将文件发布到REST服务的方法。 ( RestRequst.AddFile() ). RestRequst.AddFile() )。 I believe on the server-side this will translate into an encoded string into the body, with the content-type in the header specifying the file type. 我相信在服务器端,这将转换为正文中的编码字符串,标题中的content-type指定文件类型。

I've also seen it done by converting a stream to a base-64 string, and transferring that as one of the properties of the serialized json/xml object. 我也看到它通过将流转换为base-64字符串,并将其作为序列化json / xml对象的属性之一进行传输。 Especially if you can set size limits and want to include file meta-data in the request as part of the same object, this works really well. 特别是如果您可以设置大小限制并希望在请求中包含文件元数据作为同一对象的一部分,这非常有效。

It really depends how large your files are though. 这实际上取决于你的文件有多大。 If they are very large, you need to consider streaming, of which the nuances of that is covered in this SO post pretty thoroughly: How do streaming resources fit within the RESTful paradigm? 如果它们非常大,你需要考虑流式传输,其中的细微差别在这个SO帖子中非常详尽: 流式传输资源如何适应RESTful范式?

Building on to @MutantNinjaCodeMonkey's suggestion of RestSharp. 建立在@ MutantNinjaCodeMonkey对RestSharp的建议之上。 My use case was posting webform data from jquery's $.ajax method into a web api controller. 我的用例是将jquery的$.ajax方法中的webform数据发布到web api控制器中。 The restful API service required the uploaded file to be added to the request Body. restful API服务需要将上传的文件添加到请求Body中。 The default restsharp method of AddFile mentioned above caused an error of The request was aborted: The request was canceled . 上面提到的AddFile的默认restsharp方法导致错误The request was aborted: The request was canceled The following initialization worked: 以下初始化工作:

// 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") }
};

First, you should login to the server and get an access token.首先,您应该登录到服务器并获取访问令牌。

Next, you should convert your file to stream and post the stream:接下来,您应该将文件转换为 stream 并发布 stream:

private void UploadFile(FileStream stream, string fileName)
{
    string apiUrl = "http://example.com/api";
    var formContent = new MultipartFormDataContent
                {
                    {new StringContent(fileName),"FileName"},
    
                    {new StreamContent(stream),"formFile",fileName},
                };
    using HttpClient httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("Authorization", accessToken);
    var response = httpClient.PostAsync(@$"{apiUrl}/FileUpload/save", formContent);
    var result = response.Result.Content.ReadAsStringAsync().Result;
}    

In this example, we upload the file to http://example.com/api/FileUpload/save and the controller has the following method in its FileUpload controller:在此示例中,我们将文件上传到http://example.com/api/FileUpload/save并且 controller 在其FileUpload controller 中具有以下方法:

[HttpPost("Save")]
public ActionResult Save([FromBody] FileContent fileContent)
{
    // ...
}

public class FileContent
{
    public string FileName { get; set; }
    public IFormFile formFile { get; set; }
}
 
  1. Detect the file/s being transported with the request. 使用请求检测正在传输的文件。
  2. Decide on a path where the file will be uploaded (and make sure CHMOD 777 exists for this directory) 确定将上载文件的路径(并确保此目录存在CHMOD 777)
  3. Accept the client connect 接受客户端连接
  4. Use ready library for the actual upload 使用ready库进行实际上传

Review the following discussion: REST file upload with HttpRequestMessage or Stream? 查看以下讨论: 使用HttpRequestMessage或Stream上传REST文件?

You could send it as a POST request to the server, passing file as a FormParam. 您可以将其作为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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM