cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Share your feedback on the Document Scanning Experience in the Dropbox App right 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: 

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

Nathan L.2
New member | Level 1

Thanks Qiming, I managed to get it to work using signarR, was using this guide mostly

http://stackoverflow.com/questions/30711074/using-signalr-hub-from-mvc-action

Here's my code if anyone else wants to do it

In my controllor create action 

Snippet

var dropBoxService = new DropboxService(uploadFile, fileName);
                    var task = Task.Run((Func<Task>)dropBoxService.Upload);
                    task.Wait();

 

Then In my DropboxService Class

Snippet

public class DropboxService
    {
        private readonly HttpPostedFileBase _file;
        private readonly string _fileName;
 
        public DropboxService(HttpPostedFileBase file, string fileName)
        {
            this._file = file;
            this._fileName = fileName;
        }
 
        public async Task Upload()
        {
            // Specify socket level timeout which decides maximum waiting time when on bytes are
            // received by the socket.
 
            var httpClient = new HttpClient(new WebRequestHandler { ReadWriteTimeout = 10 * 1000 })
            {
                // Specify request level timeout which decides maximum time taht can be spent on
                // download/upload files.
                Timeout = TimeSpan.FromMinutes(20)
            };
 
            var dbx = new DropboxClient(ConfigurationManager.AppSettings["DropBoxAccessToken"], httpClient: httpClient);
            using (dbx)
            {
                const int chunkSize = 1024 * 1024;
 
                const string folder = "/CandidateTasks";
 
                using (var mem = _file.InputStream)
                {
                    if (mem.Length <= chunkSize)
                    {
                        await dbx.Files.UploadAsync(
                            folder + "/" + _fileName,
                            WriteMode.Overwrite.Instance,
                            body: mem);
                    }
                    else
                    {
                        Console.WriteLine("Start chunk uploading");
                        var path = folder + "/" + _fileName;
                        await ChunkUpload(path, mem, chunkSize, dbx);
                    }
                }
            }
        }
 
        private static async Task ChunkUpload(string path, Stream stream, int chunkSize, DropboxClient client)
        {
            var numChunks = (int)Math.Ceiling((double)stream.Length / chunkSize);
            var buffer = new byte[chunkSize];
            string sessionId = null;
            // Initialize Hub context
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
            hubContext.Clients.All.sendMessage("Initalizing...", 0);
            for (var idx = 0; idx < numChunks; idx++)
            {
                var byteRead = stream.Read(buffer, 0, chunkSize);
                Debug.WriteLine("Idx " + idx);
                using (var memSream = new MemoryStream(buffer, 0, byteRead))
                {
                    if (idx == 0)
                    {
                        var result = await client.Files.UploadSessionStartAsync(memSream);
                        sessionId = result.SessionId;
                    }
                    else
                    {
                        var cursor = new UploadSessionCursor(sessionId, (ulong)(chunkSize * idx));
                        decimal complete = chunkSize * idx;
                        decimal fileSize = stream.Length;
                        var percentageComplete = (complete / fileSize) * 100;
 
                        // Indicate file is being uploaded
                        hubContext.Clients.All.sendMessage("Uploading To Dropbox: ", (int)percentageComplete);
 
                        if (idx == numChunks - 1)
                        {
                            await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memSream);
                        }
                        else
                        {
                            await client.Files.UploadSessionAppendAsync(cursor, memSream);
                        }
                    }
                }
            }
            hubContext.Clients.All.sendMessage("Attachment Uploaded ", 100);
        }

 

 

In my view I have

Snippet

@using (Html.BeginForm("Create", "CandidateTask", FormMethod.Post, new { enctype = "multipart/form-data", id = "form1" }))
{ 
blah blah
Snippet
<input name="uploadFile" type="file" accept=".jpg, .jpeg, .png, .gif,
                  .doc, .pdf, .ppt, .odt, .xls, .xlsx, .zip, .rar,
                  .mp3, .m4a, .ogg, .wav,
                  .mov, .mpg, .ogv, .3gp, .3g2, .wmv, .mp4" />
           <div class="alert alert-warning">
               <strong>Warning!</strong> Uploaded attachments must only...
           </div>
           <br />
 
           <input type="submit" id="button1" value="Create New Task" class="btn btn-success" />
           <span id="msg" style="color:red;" />


Then I have the progress bar
Snippet
<div class="col-lg-12">
    <div id="status"></div>
</div>
 
<div class="col-lg-12">
    <div class="progress">
        <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 20px;">
            0%
        </div>
    </div>
</div>

The script I use in the view is
Snippet
<!-- Progress Indicator Column -->
<script type="text/javascript" language="javascript">
 
    $(document).ready(function () {
        $('.progress').hide();
        $('#button1').on('click', function () {
            $('#form1').submit();
        })
 
        $('#form1').on('submit', function (e) {
            var thisForm = this;
            e.preventDefault();
 
            $.ajax({
                url: '/CandidateTask/Create',
                type: "POST",
 
                data: new FormData(this),
                processData: false,
                contentType: false,
                success: function (data) {
                    console.log("done");
                    var success = data.success;
                    var errorMsg = data.errorMsg;
                    if (success === true) {
                        var targetUrl = '/CandidateTask/Index';
                        $(thisForm).load(targetUrl);
                    } else {
                        //alert(data.errorMsg);
                        $("#msg").html(data.errorMsg);
                    }
 
                    //    alert("errorsdsdf" + data.errorMessage + data.success);
                }
 
            });
 
            // initialize the connection to the server
            var progressNotifier = $.connection.progressHub;
 
            // client-side sendMessage function that will be called from the server-side
            progressNotifier.client.sendMessage = function (message, count) {
                // update progress
                UpdateProgress(message, count);
            };
 
            // establish the connection to the server and start server-side operation
            $.connection.hub.start().done(function () {
                // call the method CallLongOperation defined in the Hub
                progressNotifier.server.callLongOperation();
            });
        });
    });
 
    function UpdateProgress(message, count) {
 
        // get status div
        var status = $("#status");
 
        // set message
        status.html(message);
 
        // get progress bar
        if (count > 0) {
            $('.progress').show();
        }
 
        $('.progress-bar').css('width', count + '%').attr('aria-valuenow', count);
        $('.progress-bar').html(count + '%');
 
    }
</script>
And in my shared layout 
Snippet
@Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/signalr")
    @Scripts.Render("/signalr/hubs")
    <script src="http://malsup.github.com/jquery.form.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.2.0.js" type="text/javascript"></script>
 
   
    @RenderSection("scripts", false)
I use the same startup and progress Hub as in the stack overflow example.

last of all in my controller I return true/false result back
Snippet
var result = new { success = false, errorMsg = "ERRORRR" };
          return Json(result, JsonRequestBehavior.AllowGet);

Bit messy but may help some people so thought I'd share

Nishant D.
New member | Level 1

Uploading in chunks the logic given is great. superb.

Thanks for the help.

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Nishant D. New member | Level 1
  • User avatar
    Nathan L.2 New member | Level 1
  • User avatar
    Qiming Y. Dropbox Staff
  • User avatar
    Nenciu D. New member | Level 1
What do Dropbox user levels mean?