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?
source to share
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.
source to share