简体   繁体   English

使用Restsharp PCL上传到保管箱

[英]Upload to dropbox using Restsharp PCL

I am trying to upload a file to Dropbox using PCL using RestSharp.Portable. 我正在尝试使用RestSharp.Portable使用PCL将文件上传到Dropbox。 My code is 我的代码是

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;
}

Here is the Actual REST Call being Made 这是实际的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--

And the response from DropBox 还有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

I also removed the request.AddParameter("file", fileName); 我还删除了request.AddParameter("file", fileName); with a response from Dropbox 来自Dropbox的回复

{"error": "Forbidden"}

What am I doing wrong here? 我在这里做错了什么?

NOTE: This implementation needs to be in a PCL where it will be shared between WP8, Xamarin.Android, Xamarin.IOS, Windows WPF. 注意:此实现必须在PCL中,在该PCL中将在WP8,Xamarin.Android,Xamarin.IOS,Windows WPF之间共享该实现。

Update: 更新:

Though I had tried the PUT (files_put) api call previously, I got it working now, by changing the path to sandbox instead of dropbox as my app only has access to its own folder. 尽管我之前尝试了PUT(files_put)api调用,但由于将应用程序只能访问其自己的文件夹,因此将其更改为沙箱而不是dropbox的路径,从而使它现在可以工作了。 Here is the code that may help others. 这是可以帮助他人的代码。

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;
}

Here is the Response Entity 这是响应实体

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; }
    }
}

/files (POST) isn't a multipart form upload. /files (POST)不是分段上传。 As the docs say "...the entire POST body will be treated as the file". 正如文档所说:“ ...整个POST正文将被视为文件”。

I'd give more advice on how to construct the right kind of HTTP request, but honestly, I've never even used this endpoint, and I suggest you don't either. 我将就如何构造正确的HTTP请求提供更多建议,但老实说,我什至从未使用过该端点,并且我建议您也不要使用。 As the docs say, "We recommend you use /files_put instead due to its simpler interface." 正如文档所说,“由于界面更简单,建议您改用/files_put 。” I'd suggest using that and just adding the file contents as the body of the request. 我建议使用它,然后将文件内容添加为请求的正文。

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

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