thmshd
thmshd

Reputation: 5847

ASP.NET MVC Return File result with additional data to process on client side

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

Answers (2)

thmshd
thmshd

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

JuhaKangas
JuhaKangas

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

Related Questions