How to check if file upload is complete in Web API

I am working on an issue where a user can upload data in excel format. The data is dynamically generated (as a shared list) and then written as an excel file which works great.

Problem:

The problem I am facing is when the data is huge it takes a few seconds to download the file. During this time, I need to show some kind of progress / indication to end users (say downloading ... messages). With the current code, I cannot track when the file upload is complete ...

Here is my code ,

JS code that passes web-api method and search criteria

var request = {};
request.Code = codeDdl.find(':selected').val();

$.blockUI({ message: '<h3>Downloading...</h3>' });
//Export to Excel all records
$().largeDownload("api/FileDownload/GetWorkQueueList", {
   'request': JSON.stringify(request)
});

      

JS code that reads the search criteria and passes it to the web api method:

(function (d) {
    d.fn.largeDownload = function (a, b, c) { void 0 !== c ? (c = c.toUpperCase(), "GET" != c && (c = "POST")) : c = "POST"; if (void 0 === b || !1 == b) b = d().parse_url(a), a = b.url, b = b.params; var e = d("<form></form"); e.attr("method", c); e.attr("action", a); for (var f in b) a = d("<input />"), a.attr("type", "hidden"), a.attr("name", f), a.attr("value", b[f]), a.appendTo(e); d("body").append(e); e.bind("submit", DownloadedCallback); e.submit() }; d.fn.parse_url = function (a) {
        if (-1 == a.indexOf("?")) return { url: a, params: {} }; var b = a.split("?"), a = b[0], c = {}, b = b[1].split("&"), e = {}, d; for (d in b) {
            var g =
            b[d].split("="); e[g[0]] = g[1]
        } c.url = a; c.params = e; return c
    }
})(jQuery);

      

Web interface

    [HttpPost]
    public HttpResponseMessage GetWorkQueueList()
    {
        var resp = new HttpResponseMessage(HttpStatusCode.OK);
        var currentContext = HttpContext.Current;

        try
        {
            string strRequest = currentContext.Request.Form["request"];
            var serializer = new JavaScriptSerializer();
            var request = serializer.Deserialize<ViewRequest>(strRequest);
            request.QueryAllRecords = true;
            var workQueueList = MappingManager.GetWorkQueueList(request);

            var legacyExcelView = //get data as generic list
            ....
            ....

            var fileBytes = ExcelManager.GetExcelData<WQExcelView>(legacyExcelView);
            var stream = new MemoryStream(fileBytes);
            resp.Content = new StreamContent(stream);
            resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            resp.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "WorkQueueList.xlsx" };
            resp.Content.Headers.Add("Content-Encoding", "UTF-8");
            return resp;
        }
        catch (Exception ex)
        {                
            resp.Content = new StringContent(ex.Message);
            return resp;
        }
    }

      

What I have tried:

In the big Download javascript function I added DownloadedCallback which doesn't seem to work as I expect. It starts immediately and before loading.

Question:

How to check if a file upload is complete in a Web API method ... What should I do to display a progress bar until the file upload dialog is displayed?

+3


source to share


1 answer


We usually solve the problem with 2-3 API calls. Our applications are written in Java; however, the same basic principle applies here.

The first call is to initiate a large SQL query, create a large file, etc. in a separate thread . This request is returned immediately, sometimes with an ID to reference the original request.



While CSV strings are being written in the spawned stream, we are writing two property values ​​in the original stream for the number of lines processed and total lines. If it's a large SQL statement, we often expose the statement itself to a few limited SQL statements so that progress values ​​can be set gradually and displayed, instead of sitting at 0% for a while and then bind to 100%. Bursting SQL queries often only comes at an extra cost in milliseconds, but gives a ton of value in terms of user experience.

We have a second API call that is polled and then returns the property values ​​for the count and total processed. This is what we use to animate our progress bar. When it reaches 100% or a status flag when responding to this call, we often request the finished file in a separate API call. You can also return the file pointer / path in the same turn.

0


source







All Articles