3

I have an old MVC 1.0 application that I am struggling with something relatively simple.

  1. I have a view that allows the user to upload a file.
  2. Some server side processing goes on.
  3. Finally, a new file is generated and downloads automatically to the client's machine.

I have steps 1 and 2 working. I can not get the final step to work. Here is my controller:

[AcceptVerbs(HttpVerbs.Post)]
public ViewResult SomeImporter(HttpPostedFileBase attachment, FormCollection formCollection, string submitButton, string fileName
{
    if (submitButton.Equals("Import"))
    {
        byte[] fileBytes = ImportData(fileName, new CompanyExcelColumnData());
        if (fileBytes != null)
        {
            RedirectToAction("DownloadFile", "ControllerName", new { fileBytes = fileBytes});
        }
        return View();
    }
    throw new ArgumentException("Value not valid", "submitButton");
}

public FileContentResult DownloadFile(byte[] fileBytes)
{
    return File(
                fileBytes,
                "application/ms-excel",
                string.Format("Filexyz {0}", DateTime.Now.ToString("yyyyMMdd HHmm")));
}

The code executes:

RedirectToAction("DownloadFile", "ControllerName", new { fileBytes = fileBytes});

but the file does not download. Suggestions welcome and thanks in advance.

Seany84
  • 5,526
  • 5
  • 42
  • 67
  • 1
    `RedirectToAction` sends an HTTP redirect to the browser, so passing file data won't work. Can you just return `File()` in place of the redirect? – Tim M. Feb 07 '13 at 00:43
  • 1
    You could also put the data in `TempData` (assuming it was in version 1...don't recall) – Tim M. Feb 07 '13 at 00:44
  • I have tried returning the `File()` instead of the `RedirectToAction` but it did not work either. When you say put the `byte[]` into `TempData` how will I get it to download from the controller's `SomeImporter()` ? – Seany84 Feb 07 '13 at 00:53
  • 1
    What did returning `File()` do? was there an error? To use `TempData`, you would put the bytes into it `TempData["foo"] = fileBytes`, perform the redirect, then get the bytes out of it in your download action. – Tim M. Feb 07 '13 at 00:58
  • I can't return the file, compile time error: `Cannot implicitly convert type 'System.Web.Mvc.FileContentResult' to 'System.Web.Mvc.ViewResult'`. I'm going to try the `TempData` approach now. – Seany84 Feb 07 '13 at 01:00
  • 1
    Okay...you can also try returning `ActionResult` rather than `ViewResult`. – Tim M. Feb 07 '13 at 01:02

2 Answers2

4

Try to return ActionResult, because it is the most abstract class of the output of actions. ViewResult will force you to return a View or PartialView, so, return a File will get an exception about implicitly converttion type.

[HttpPost]
public ActionResult SomeImporter(HttpPostedFileBase attachment, FormCollection formCollection, string submitButton, string fileName
{
    if (submitButton.Equals("Import"))
    {
        byte[] fileBytes = ImportData(fileName, new CompanyExcelColumnData());
        if (fileBytes != null)
        {
            return File(
                fileBytes,
                "application/ms-excel",
                string.Format("Filexyz {0}", DateTime.Now.ToString("yyyyMMdd HHmm")));
        }
        return View();
    }
    throw new ArgumentException("Value not valid", "submitButton");
}
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
2

Why do RedirectToAction? Can you return File from SomeImporter action, just change the return type of SomeImporter to FileContentResult.

Sergey
  • 2,303
  • 1
  • 18
  • 11