cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
What’s new: end-to-end encryption, Replay and Dash updates. Find out more about these updates, new features and more here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Re: CSharp SDK await dbx.Files.UploadAsync(...) object gets disposed before upload

CSharp SDK await dbx.Files.UploadAsync(...) object gets disposed before upload

Continuous I.
New member | Level 1

Hi, although I've mastered uploading text content to Dropbox, when trying to upload byte content (typical file, 18 MB), I get the error:

"ERROR: The object was used after being disposed"

The code is as follows, and the error was thrown in a try-catch in the second code block:

 

using (var dbx = new DropboxClient("My_Token"))
{
await UploadToDropBox(dbx, "/test", IPATargetFileName, fullPathToFileToUpload);
}
// the method called is in the next code block

async Task UploadToDropBox(DropboxClient dbx, string dropboxfolder, string dropboxfilename, string filepathtoUpload)
{
using (var mem = new MemoryStream(File.ReadAllBytes(filepathtoUpload)))
{
try
{
var updated = await dbx.Files.UploadAsync(
dropboxfolder + "/" + dropboxfilename,
WriteMode.Overwrite.Instance,
body: mem);
}
catch (Exception ex)
{
LogMessage(string.Format(" : ERROR: {0}", ex.Message));
}
}
}
 

I'm, guessing that this is a MemoryStream / FileStream problem but the API example only shows how to upload a text file.

Kind regards,

Anthony

 

 

21 Replies 21

Steve M.
Dropbox Staff

Continuous I.
New member | Level 1

Steve: thanks for the tip, from which I presume there's no capacity in the SDK to upload large files.

Qiming: If you have any further information on how to easily do this, I'd be grateful.  

As this is for a series of Continuous Integration projects (Automated Builds), I'll first see if the Google Drive SDK or OneDrive SDK can handle large file uploads in the interim, I have a next Monday delivery window on this proof of concept.

However I'd be very interested to be supplied with some boilerplate code for this, CI + Dropbox is one example of Dropbox use where each and every instance of it's use is virtually guaranteed of having to undertake a paid subscription because of CI typically keeps the accumulated results.

Thanks, and Kind regards,

Anthony

Steve M.
Dropbox Staff

"Steve: thanks for the tip, from which I presume there's no capacity in the SDK to upload large files."

I'm not sure that you mean. That's precisely what those methods I linked to are for.

 

Continuous I.
New member | Level 1

Steve, my mistake, when you said .Net SDK I thought you were referring to the .Net HttpClient API & etc, instead of the Dropbox SDK, I'll take a look, that's great news indeed as Dropbox is our first choice, thanks again!

Qiming: If you have any boilerplate code for this, I'd appreciate it!

Kind regards,

Anthony

Qiming Y.
Dropbox Staff

Below is example code about how to do chunk upload.

 private async Task Upload(string file)
{
const string TargetPath = "/test.zip";
const int ChunkSize = 4096 * 1024;
using (var fileStream = File.Open(file, FileMode.Open))
{
if (fileStream.Length <= ChunkSize)
{
await this.client.Files.UploadAsync(TargetPath, body: fileStream);
}
else
{
Console.WriteLine("Start chunk uploading");
await this.ChunkUpload(TargetPath, fileStream, ChunkSize);
}
}
}

private async Task ChunkUpload(String path, FileStream stream, int chunkSize)
{
int numChunks = (int)Math.Ceiling((double)stream.Length / chunkSize);
byte[] buffer = new byte[chunkSize];
string sessionId = null;
for (var idx = 0; idx < numChunks; idx++)
{
var byteRead = stream.Read(buffer, 0, chunkSize);

using (var memSream = new MemoryStream(buffer, 0, byteRead))
{
if (idx == 0)
{
var result = await this.client.Files.UploadSessionStartAsync(memSream);
sessionId = result.SessionId;
}
else
{
var cursor = new UploadSessionCursor(sessionId, (ulong)(chunkSize * idx));

if (idx == numChunks - 1)
{
await this.client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memSream);
}
else
{
await this.client.Files.UploadSessionAppendAsync(cursor, memSream);
}
}
}
}
}

Continuous I.
New member | Level 1

Qiming, thank you very much indeed, once I get all of this finished I'll blog it as payback, once again, thanks!

Kind regards,

Anthony

AnthonyHarrison
New member | Level 2

Qiming, it works like a dream, and thanks so much, I'll create a Nuget package soon that specifically targets CI with built in logging.

Kind regards,

Anthony

Nenciu D.
New member | Level 1

Thanks Qiming. 

Nathan L.2
New member | Level 1

Cheers Qiming,

I was wondering if there was a way to pass a value from the upload chunks to the view so the user can see how long is left of the upload.

The user presses a submit button and  this calls an actionResult method in the controller which gets the file and uploads to dropbox using above method.

Currently have this in the Upload Chunks method.

decimal complete = chunkSize * idx;
decimal fileSize = stream.Length;
decimal percentageComplete = (complete / fileSize) * 100;

Wondering if there was any way to get the percentageComplete value to display in the view?
Thanks

 

Qiming Y.
Dropbox Staff

Hi Nathan,

I think this is not sdk level thing. What you need is a way to get progress for some long running action in MVC application. I think with SignalR you may be able to do that.

Need more support?