Following on from my previous post where I showed you how to Login and get the Account Info for a Dropbox account. Today we dive into the Box full of files. Uploading, Downloading and Deleting!
A lot has changed since my last post in the way of RestSharp with OAuth. OAuth is now available Out-of-the-box (this can be downloaded from Github). Ok, Time for some code…
Download File:
Update: Fixed a bug in the code that only allowed for text based files to be downloaded. Using restClient.DownloadData now instead of Execute to get the response’s raw Data.
public byte[] DownloadFile(string path)
{
var restClient = new RestClient("http://api-content.dropbox.com");
//load the JsonDeserializer for all types
restClient.ClearHandlers();
restClient.AddHandler("*", new JsonDeserializer());
if (!path.StartsWith("/")) path = "/" + path;
restClient.Authenticator = new OAuthAuthenticator(restClient.BaseUrl, _apiKey, _appsecret, _userLogin.Token, _userLogin.Secret);
var request = new RestRequest(Method.GET);
request.Resource = "{version}/files/dropbox{path}";
request.AddParameter("version", _version, ParameterType.UrlSegment);
request.AddParameter("path", path, ParameterType.UrlSegment);
var responseData = restClient.DownloadData(request);
return responseData;
}
Note: This is assuming the user has already logged in and we have the token/secret (_userLogin).
Starting from the top, we create a new Instance of the RestSharp Client with the baseUrl then set the Json Deserializer for all requests. We then set the RestClient’s Authenticator to the OAuthAuthenticator and give it our baseUrl, all our secrets and that is all we need to do for OAuth (the rest is build into RestSharp, awesome?!). Now we create the Request up, its a GET method, set the version and path of the file to download call Execute and you have just downloaded your first Dropbox API file! I then converted this to a stream so save back to a local file.
Delete File:
public bool DeleteFile(string path)
{
var restClient = new RestClient("http://api.dropbox.com");
//load the JsonDeserializer for all types
restClient.ClearHandlers();
restClient.AddHandler("*", new JsonDeserializer());
if (!path.StartsWith("/")) path = "/" + path;
restClient.Authenticator = new OAuthAuthenticator(_restClient.BaseUrl, _apiKey, _appsecret, _userLogin.Token, _userLogin.Secret);
var request = new RestRequest(Method.GET);
request.Resource = "{version}/fileops/delete";
request.AddParameter("version", _version, ParameterType.UrlSegment);
request.AddParameter("path", path);
request.AddParameter("root", "dropbox");
var response = restClient.Execute(request);
return response.StatusCode == System.Net.HttpStatusCode.OK;
}
Delete is pretty similar to Download, only differences is the Url, the response and this time the path is sent as a parameter instead of part of the Url. The “root” parameter is for applications that only have sandbox access (they would set this to sandbox) who only get access to a “sandbox” folder on the users dropbox account.
Upload File:
Now this is where I had the most difficulties, many “Forbidden” messages later I finally came up with the solution!
public bool UploadFile(string path, FileInfo localFile)
{
var restClient = new RestClient("http://api-content.dropbox.com");
//load the JsonDeserializer for all types
restClient.ClearHandlers();
restClient.AddHandler("*", new JsonDeserializer());
if (!path.StartsWith("/")) path = "/" + path;
//Get the file stream
byte[] bytes = null;
FileStream fs = new FileStream(localFile.FullName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = localFile.Length;
bytes = br.ReadBytes((int)numBytes);
restClient.Authenticator = new OAuthAuthenticator(_restClient.BaseUrl, _apiKey, _appsecret, _userLogin.Token, _userLogin.Secret);
var request = new RestRequest(Method.POST);
request.Resource = "{version}/files/dropbox{path}";
request.AddParameter("version", _version, ParameterType.UrlSegment);
request.AddParameter("path", path, ParameterType.UrlSegment);
//Need to add the "file" parameter with the file name
request.AddParameter("file", localFile.Name);
request.AddFile(new FileParameter { Data = bytes, FileName = localFile.Name, ParameterName = "file" });
var response = restClient.Execute(request);
return response.StatusCode == System.Net.HttpStatusCode.OK;
}
Ok to start with the “path” variable/parameter is the folder path (not the file).
Starts off the same with the RestClient, JsonDeserializer and the OAuthAuthenticator. We also need to read the file as a byte array. Now this request is a POST so we set that in the RestRequest object then add the version and path Url parameters. We also need to add the Filename as a “file” parameter for this request as well as adding the actual file to the Request. Execute that and: {\"result\": \"winner!\"} we just uploaded a file to dropbox!
This code was taken from my Dropbox open source .NET project called DropNet.
AddFile() should take a string to the full path saving you the effort of having to populate the FileParameter yourself.
Thats a good idea. I did it that way so I could add the ParameterName property the file objects.
Pingback: Tweets that mention Dropbox API, RestSharp and C# Part 2: The Revenge! « DK Development -- Topsy.com
Is there any way to tell what percentage of a file has been sync’d
Was trying this out and it looks good. However I have a small issue (which I can work around) in that all my files are returned with a modified time of 1/1/1. Not sure whether this is a timezone issue as I’m based in the UK.
I changed the property in MetaData.cs to a string and I get back values such as Wed, 19 Jan 2011 23:48:07 +0000 which parses correctly using DateTime.Parse.
I downloaded the .NET solution and ran the tests. The one that REALLY didn’t work was the upload file test. I tried implementing it using real data and it still didn’t work. Currently it seems that there is a multipart vs. chunked encoding issue, and I may have to write a REST client from scratch for the upload function.
Very nice library, very simple to use. I am wondering if there way to get actual “public” path for files on Dropbox side? Dropbox API seems don’t have any method/properties. For example if I want stream files, i can try use save file to HTTP request output stream, at momnet user click links, but i also want to “share” links between apps?
@Eugene, At the moment there is not function to get a files public path as the API doesnt have a function for this directly. But this can be easily created with the use of the Account Info function to get the users UserID then the path to the file in the public folder (or copying the file to Public).
Once you have those things its as simple as: http://dl.dropbox.com/u/USERID/FILEPATH
Thanks, you made it really simple. At least it is one option to share through Public folder.
But I guess if I want share between visitors who are Dropbox users and has account, I can still “request” and get file listing on behalf another users, as soon as they agreed to share of course, whihtout exposing original users credential to client and save files or stream. It should work, right?
When i try to upload a 30MB I get timeout error, but the same works great for a 1 mb word document. I am using the following :
UploadFile(“/test”,”Preview.m4v”,data); where data is a byte array.
Any suggestions,
How do you do a multi-part upload. Lets say you plan to upload a 11GB file on DropBox, there is no way you are going to load the entire file in memory.
urgent.
Hi I am using the dropnet client. I got the API Key/secret from drop box site.
my requirement in which we are giveing option to create new drop box user from our wp7 application .
Because here we are getting the key/sec using the diffrent userid(let abc@gmail.com ) now we have created the new user
xyz@gmail.com but using this id LoginAsync method is returning forbidden exception.
can you please help me . how to use
@Ashwini, Sounds like your API key is set to Development mode, which means only your account that you used to create the Key with has access to Dropbox using that Key.
Damian,
Thank you for a great tutorial. We have a web app that allows people to share files by storing the files in the dropbox folder. The upload to dropbox process works great by using restClient to communicate to the dropbox api. However I can’t seem to upload .docx and .xlsx files. When I use the dropbox api to upload the files, I can’t view them when they get into the dropbox folder. When I open a .docx file that has been uploaded through the api, it says it is corrupted. Have you tried before to upload a .docx (Microsoft Office 2007) file using the api? What advice can you give me on this issue? Any help greatly appreciated. Just to mention again, .doc and other files such as .pdf are always uploaded correctly and do show correctly.
Thanks,
Dun
@Dun, Are you using DropNet from NuGet or were you just using the code from this post? I’d recommend getting it from NuGet if you arent already as I have just released v1.8 with a few bug fixes. However, if you still find the bug there could you please submit an issue on Github (https://github.com/dkarzon/DropNet/issues) and I’ll try to fix it for the next release.
When I upload a docx file using the above “Upload File” code, everything works fine. I am able to see my file in my dropbox folder. However I am still not sure why my Microsoft word 2007-2010 files are corrupted when I view them. I tried to use DropNet but I don’t seem to get it to work. Does anyone have a simple tutorial app that uploads a file to dropbox using the dropbox api?
I also changed the docx file to a zip package and looked through the xml. There was no difference between the original file and the file uploaded to dropbox. Please can someone also try to upload a Microsoft office 2007 – 2010 file to dropbox using the dropbox api? I can’t seem to figure out why these files come back corrupted after being uploaded to dropbox. The upload process is always going well. Any help greatly appreciated.
@Dun, That was actually a bug with RestSharp that should have been fixed, it was adding an extra line break to the end of uploaded files. Have a look at the open source library DropNet (https://github.com/dkarzon/DropNet) it might help you out.
I look at the library DropNet (https://github.com/dkarzon/DropNet) and used the upload file method. Dropnet is using a newer version of RestSharp dll. I can upload files to dropbox without a problem. The fix for the end of line problem seem not to help much. When viewing the file that has been uploaded to dropbox, a dialog window still pops up saying “somefile.docx cannot be opened because there are problems with the contents.” When I click OK, another dialog window says, “Word found unreadable content in somefile.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes”. – When I click Yes, I get the file to appear correctly! However it opens as Document1[Compatibility Mode]. Damian have you ever tried to upload a docx or xlsx file.