1

I am new to MVC. I have an index page. Which displays a list of items to the user. The user can then add a new item. After the user has added the new item a file is downloaded for them containing sensitive the information they added. All of that works fine but....

My problem is now how to redirect them back to the index page to refresh the list of items? Its almost like I need a redirect after the download.

Note: Insert download all work fine. I am just trying to figure out how to do a redirect to another model after the download so that I can refresh my list.

I cant do the redirect first because the data that is being saved to the file is sensitive so I don't want to send it anywhere.

[Authorize]
public async Task<IActionResult> Index(int clientId, string error)
    {
     // ....... Removed
     var model = new SecretIndexModel()
        {
            Client = clients.Client,
            ErrorMessage = error
        };
        return View(model);
    }

On this page, a user can add a new item.

[Authorize]
[HttpPost]
public async Task<IActionResult> Add(SecretIndexModel model)
{

 /// removed ....

 return DownloadDocument("results json string"); 
 }

Download

 public FileResult DownloadDocument(string id)
    {
        var ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes("abc"));

        return File(ms, System.Net.Mime.MediaTypeNames.Application.Octet, "secret.json");
    }

Am I going about this wrong? I know I need to add something like this because that works if I return that instead of the download.

return RedirectToAction("Index",
       new
          {
           clientId = model.Client.Id,
           error = (client.Errors == null)
                   ? string.Empty
                   : client?.Errors?.FirstOrDefault()?.Message
          });

Update:

I can send the data over using TempData but that doesn't seem to help much I can then refresh the index page but not download the file.

Dawid Rutkowski
  • 2,658
  • 1
  • 29
  • 36
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • Use iframe or ajax [Also check this solution](https://stackoverflow.com/questions/2288941/redirecting-a-page-after-a-pdf-download) – Alex Veremeenko Apr 26 '18 at 11:20
  • Thanks for the response but i cant use ajax or iFrame. – Linda Lawton - DaImTo Apr 26 '18 at 11:28
  • 2
    A redirect and a download are two totally different response types, which is why you can't send them both in one response. What you could do is use some JavaScript to cause the download URL to be opened in a separate tab, and simultaneously change the location of the main page to a new URL. The one bit you can't do is wait for the download to complete before doing that, because that's outside the context of your view, so Javascript can't see that event, it's a totally separate HTTP request being dealt with separately by the browser. – ADyson Apr 26 '18 at 11:35
  • I was trying to avoid using JavaScript but this might be a good solution – Linda Lawton - DaImTo Apr 26 '18 at 11:37
  • Would the downvoter mind commenting on the reason I am happy to improve the question as needed if something is unclear – Linda Lawton - DaImTo Apr 27 '18 at 20:25

1 Answers1

1

As @ADyson stated in the comments, a download and a redirect are two different response, and you can only return one response. Personally, I would return the redirect and then simply include a link to download the file. You could save the link URL to TempData and present it like an alert or toast notification. You can also set a meta refresh tag to automatically request the download. For and example, check the Visual Studio download page. It loads a page with a link to download the file in case it doesn't start automatically, but then after a second or two, you get an automatic prompt to download.

If you really want to take it farther, and especially if the download takes some amount of time to create, you could start the download file creation process and immediately return the redirect. Then, using SignalR, you can notify the user when the download is actually ready or even automatically download it at that point. This provides a much more ideal user experience, again, if the download takes some period of time to create. Instead of making the user way staring at a blank page, they get a response near immediately and get their download when it's ready.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • I can't save the file on the server this is sensitive data so a link won't work. its a very small file containing client id and secret. – Linda Lawton - DaImTo Apr 26 '18 at 13:31
  • You don't need to necessarily save the file. Break out the file creation into a separate action. Save the information from the post as you normally would, and then simply return back the file creation action's URL with an id or something it can use to retrieve the information to create the file. – Chris Pratt Apr 26 '18 at 14:10
  • Thanks this works well it wasn't exactly what I was hoping for. I hoped I was doing something wrong. but it's a very elegant solution – Linda Lawton - DaImTo Apr 27 '18 at 20:27