Reputation: 5847
I'm currently collecting ideas how to solve the following issue: I'm generating Report in realtime and returning it to the browser using the File
method.
public ActionResult GenerateReport()
{
var report = ... // Don't care, we get an object containing an Id and a byte array
var reportId = report.Id; // this is actually important
return File(report.Data, "..."); // Return data with some content type, filename etc.
}
When the action is executed, the browser will prompt the file download. But I'd also somehow like to transfer the new Id
to the Browser which I need for processing.
Do you have any idea how I could solve this using the common JavaScript (jQuery) and Web/ASP.NET/Ajax or whatever techniques?
Upvotes: 0
Views: 2225
Reputation: 5847
We finally came to the result that we were able to make changes in the back end, where we're now able to request a "temporary" ID without actually starting the Report generation, while the actual Report generation now requires the ID to be provided. This is how the client side now looks:
function generateReport() {
$.ajax({
url: "/GetNewReportId", // A) This is where we get the new ID
method: 'POST'
})
.done(function (result) {
if (result) {
// The ID is returned here: result.Id
// Open the confirmation modal with Id assigned
showConfirmationModal(result.Id);
// B) This will lead to a download-prompt and leave site functioning
window.location = "/GenerateReport?id=" + resultId;
}
});
}
The action /GetNewReportId
is a simple Mvc Action returning a JsonResult
, containing the ID only. Also, the code was simplified to present you the idea, it hasn't been tested in it's final form.
There is some disadvantage though: If the process fails somewhere between steps A) and B), you might end up having some record for the unprocessed Id, which you have to clean up at some time.
Upvotes: 0
Reputation: 883
Use cookies!
Add a cookie in your response and then have looping jquery code that looks for it. In that cookie you can add the id and stop the loop once it has been found. Then just delete it again.
For example I use the ActionFilter below to detect when a file has been processed for download, using the File actionresult just like you.
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var key = filterContext.HttpContext.Request.QueryString["downloading"].ToString();
if (key != null)
{
var cookie = new HttpCookie(key);
cookie.Path = "/";
filterContext.HttpContext.Response.Cookies.Add(cookie);
}
}
Upvotes: 1