我正在尝试使用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; }
}
}