C # mvc returns JSON or file from an AJAX call

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 may return the file or may return a JSON result if an error occurs. Failed to get them to work together.

Here's 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"); } 

I see that a jax value is required to call ajax. Since in my case it returns a file, it cannot work. In any case, to handle what I'm doing, where it can return JSON or a file from an ajax call.

+4
source share
4 answers

Have you considered submitting JSON with an Url file?

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

+2
source

I think you will encounter many problems with this implementation. In fact, you cannot upload or download files through AJAX. See the link below.

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

You should use one of the two implementations separated in the question inserted above. If you use the IFRAME method, you can use jQuery to check when the document will be executed and whether it will succeed.

EDIT: you can just throw a server exception (500). How you process 500 of the IFRAME is up to you.

+3
source

Your code will never work because you cannot pass binary data into an Ajax request - you do not have the usual response context for writing.

You can use several approaches:

  • If the check passes, just return the new link to another handler that will transfer data to the user. Then you read this link to the Javascript callback function and open it in a new window.
  • Use IFRAME as suggested above by DAN Natic.
  • More complicated: Base64 encodes binary data and returns it as part of the Json result. Read the base64 encoded file, decrypt it using Javascript (many libraries for this can be found on the Internet) and do something * with the result.

* I'm not sure if this is possible with ZIP files. You may be able to display PDF files inside the browser using this method, but you are very doubtful that it will work on all browsers. I can advise you to go with option 1.

+2
source

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

WITH#:

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

All Articles