4

I have something like this in my View:

        var url = '@Url.Action("DownloadZip", "Program")' + '?programNums=' + selectedRow;

        $.ajax({
            url: url,
            dataType: 'json',
            async: false,
            success: function (data) {
                if (data != "Successful") {
                    alert(data);
                }
            }
        });

The controller can return a File or can return a JSON result if there was an error. Haven't been able to get them both work together.

Here is what it looks like:

    public ActionResult DownloadZip(string programNums)
    {

        if(string.IsNullOrEmpty(programNums))
        {
          return Json("Error, blank info sent.", JsonRequestBehavior.AllowGet);
        }            

        var memoryStream = new MemoryStream();

        using (var zip = new ZipFile())
        {
            zip.AddFile("C:\\sitemap.txt");
            zip.Save(memoryStream);
        }

        memoryStream.Seek(0, 0);
        return File(memoryStream, "application/octet-stream", "archive.zip");

    }

What I am seeing is that the ajax call needs a JSON value back. Since in my case, it returns a File, it cannot work. Anyway to handle what I am doing to where it can give back a JSON or a File from the ajax call.

3
  • In the ajax call it is specifying that it requires json as the returned type. This is different from the "application/octet-stream" being returned when you are sending the file. Try removing the line dataType: 'json' from the ajax call? Commented Dec 18, 2012 at 21:02
  • Thanks Shane - Did removed dataType: json but that didn't work. It returned the file but was not in a readable format. Close though. Commented Dec 18, 2012 at 21:06
  • I've read that AJAX is not a good method for downloading files. Here is a similar question link Commented Dec 18, 2012 at 21:12

4 Answers 4

3

I think you are going to run into a lot of problems with this implementation. You actually cannot upload or download files via AJAX. See the link below.

How to download file from server using jQuery AJAX and Spring MVC 3

You should use one of the two implementations shared in the question pasted above. If you use the IFRAME method, you may be able to use jQuery to check when the document is done and whether or not it succeeded.

EDIT: You can just throw a server exception (500). How you handle the 500 from the IFRAME is up to you.

Sign up to request clarification or add additional context in comments.

Comments

2

Have you considered passing back JSON with a file Url?

If the file is successfully found/created. Send back a JSON result with the link to the file. Then in javascript use windows.location to retrieve the file. When there is an error, the JSON result will contain the error information and this info can be displayed to the user. For this to work, you'll need to create another endpoint (action) that can stream the file.

Comments

2

Your code will never work because you can't stream binary data to an Ajax request - you don't have a normal response context to write to.

You can take several approaches:

  1. If the validation passes, simply return a new link to another handler that will stream the data to the user. You would then read this link on your Javascript callback function and open it in a new window.
  2. Use an IFRAME, as DAN Natic suggested above.
  3. More complicated: Base64-encode the binary data and return it as part of the Json result. Read the base64-encoded file, decode it using Javascript (plenty of libraries to do this are found online) and do something* with the result.

* I am not sure it's possible to do anything in the case of ZIP files. You may be able to display PDF files inline inside the browser using this technique but highly doubt that it will work on all browsers. My advise is to go with option 1.

Comments

1

Ajax: window.location = '/Home/download';

c#:

        public FileResult download()
        {
           return File("~/" + path, "application/pdf", string.Format(fileName));
        }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.