本文介绍了使用Restsharp PCL上传到保管箱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to upload a file to Dropbox using PCL using RestSharp.Portable. 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;
}

这是实际进行的REST调用

Here is the Actual REST Call being Made

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的响应

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

我还通过Dropbox的回复删除了request.AddParameter("file", fileName);

I also removed the request.AddParameter("file", fileName); with a response from Dropbox

{"error": "Forbidden"}

我在做什么错了?

注意:此实现必须在PCL中,它将在WP8,Xamarin.Android,Xamarin.IOS和Windows WPF之间共享.

NOTE: This implementation needs to be in a PCL where it will be shared between WP8, Xamarin.Android, Xamarin.IOS, Windows WPF.

更新:

尽管我以前尝试了PUT(files_put)api调用,但由于将应用程序更改为沙箱而不是Dropbox的路径,因此我现在可以正常使用了,因为我的应用只能访问其自己的文件夹.这是可以帮助他人的代码.

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

这是响应实体

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

推荐答案

不是多部分表单上传.正如文档所说的:"...整个POST正文将被视为文件".

/files (POST) isn't a multipart form upload. As the docs say "...the entire POST body will be treated as the file".

我将就如何构造正确的HTTP请求提供更多建议,但老实说,我什至从未使用过该端点,并且我建议您也不要使用.正如文档所述,我们建议您使用 /files_put 代替界面更简单."我建议使用它,然后将文件内容添加为请求的正文.

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. As the docs say, "We recommend you use /files_put instead due to its simpler interface." I'd suggest using that and just adding the file contents as the body of the request.

这篇关于使用Restsharp PCL上传到保管箱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-01 05:13