代码之家  ›  专栏  ›  技术社区  ›  Nap Zoom

使用Restsharp PCL上载到dropbox

  •  1
  • Nap Zoom  · 技术社区  · 11 年前

    我正在尝试使用RestSharp.Portable使用PCL将文件上载到Dropbox。我的代码是

    public async Task<object> UploadFile(Stream fileStream, string fileName)
    {
        var client = new RestClient("https://api-content.dropbox.com");
        client.ClearEncodings();
        client.AddEncoding("gzip", new GzipEncoding());
    
        var request = new RestRequest("1/files/dropbox/Apps/FileBolt", HttpMethod.Post);
        request.AddHeader("Authorization", string.Format("Bearer {0}", Token));
        request.AddParameter("file", fileName);
    
        byte[] bytes = null;
        long numBytes = fileStream.Length;
    
        using (var br = new BinaryReader(fileStream))
        {
            bytes = br.ReadBytes((int) numBytes);
        }
    
        request.AddFile(new FileParameter { ContentLength = numBytes, FileName = fileName, Name = "file", Value = bytes });
    
        var boxItemResponse = await client.Execute<Entities.Cloud.Dropbox.File>(request);
        if (boxItemResponse != null && boxItemResponse.Data != null)
        {
            return boxItemResponse.Data;
        }
    
        return null;
    }
    

    以下是实际的REST调用

    POST https://api-content.dropbox.com/1/files/dropbox/Apps/FileBolt HTTP/1.1
    Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXX
    Accept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml
    Accept-Encoding: gzip
    Content-Type: multipart/form-data; boundary="0ab9510a-e347-4871-96c0-14b11b382435"
    Host: api-content.dropbox.com
    Content-Length: 20205
    Expect: 100-continue
    
    --0ab9510a-e347-4871-96c0-14b11b382435
    Content-Type: text/plain; charset=utf-8
    Content-Disposition: form-data; name=file
    
    driver.png
    --0ab9510a-e347-4871-96c0-14b11b382435
    Content-Length: 19865
    Content-Disposition: form-data; name=file; filename=driver.png; filename*=utf-8''driver.png
    
    {BYTES}
    --0ab9510a-e347-4871-96c0-14b11b382435--
    

    DropBox的响应

    HTTP/1.1 400 Bad Request
    Server: nginx
    Date: Sat, 22 Mar 2014 12:16:07 GMT
    Content-Type: application/json
    Transfer-Encoding: chunked
    Connection: keep-alive
    
    2e
    {"error": {"file": "Expecting a file upload"}}
    0
    

    我还删除了 request.AddParameter("file", fileName); 来自Dropbox的响应

    {"error": "Forbidden"}
    

    我在这里做错了什么?

    注意:此实现需要在PCL中,它将在WP8、Xamarin.Android、Xamari.IOS和Windows WPF之间共享。

    更新:

    虽然我以前尝试过PUT(files_PUT)api调用,但现在我已经开始工作了,因为我的应用程序只能访问自己的文件夹,所以将路径更改为沙盒而不是dropbox。以下是可能帮助他人的代码。

    public async Task<object> UploadFile(Stream fileStream, string fileName, string md5 = null)
    {
        var client = new RestClient("https://api-content.dropbox.com");
        client.ClearEncodings();
        client.AddEncoding("gzip", new GzipEncoding());
    
        var request = new RestRequest(string.Format("1/files_put/sandbox/{0}", fileName), HttpMethod.Put);
        request.AddHeader("Authorization", string.Format("Bearer {0}", Token));
    
        byte[] bytes = null;
        long numBytes = fileStream.Length;
    
        using (var br = new BinaryReader(fileStream))
        {
            bytes = br.ReadBytes((int) numBytes);
        }
    
        var body = new Parameter
        {
            ContentType = new MediaTypeHeaderValue("application/octet-stream"),
            Name = "file",
            Value = bytes,
            Type = ParameterType.RequestBody,
            ValidateOnAdd = false
        };
        request.Parameters.Add(body);
    
        var response = await client.Execute<Entities.Cloud.Dropbox.File>(request);
        if (response != null && response.Data != null)
        {
            return response.Data;
        }
    
        return null;
    }
    

    这是响应实体

    using System;
    using Newtonsoft.Json;
    
    namespace Entities.Cloud.Dropbox
    {
        public class File
        {
            [JsonProperty(PropertyName = "size")]
            public string FriendlySize { get; set; }
    
            [JsonProperty(PropertyName = "bytes")]
            public int Size { get; set; }
    
            [JsonProperty(PropertyName = "path")]
            public string Path { get; set; }
    
            [JsonProperty(PropertyName = "is_dir")]
            public bool IsDirectory { get; set; }
    
            [JsonProperty(PropertyName = "is_deleted")]
            public bool IsDeleted { get; set; }
    
            [JsonProperty(PropertyName = "rev")]
            public string Revision { get; set; }
    
            [JsonProperty(PropertyName = "hash")]
            public string Hash { get; set; }
    
            [JsonProperty(PropertyName = "thumb_exists")]
            public bool ThumbnailExists { get; set; }
    
            [JsonProperty(PropertyName = "icon")]
            public string Icon { get; set; }
    
            [JsonProperty(PropertyName = "modified")]
            public DateTime Modified { get; set; }
    
            [JsonProperty(PropertyName = "root")]
            public string Root { get; set; }
        }
    }
    
    1 回复  |  直到 11 年前
        1
  •  0
  •   user94559    11 年前

    /files (POST) 不是多部分表单上载。正如文档所说的“……整个POST主体将被视为文件”。

    我会就如何构造正确类型的HTTP请求提供更多建议,但老实说,我从未使用过这个端点,我建议您也不要。正如医生所说,“我们建议您使用 /files_put 而是由于其更简单的接口。“我建议使用它,并将文件内容添加为请求的主体。