LP13
LP13

Reputation: 34179

How to download a file using MVC & jQuery

I hope I am not re-posting the same issue, because I think this is very common issue and yes I have searched this forum, found some suggestions but they didn't work for me.

I am trying implement download functionality using MVC & jQuery. I have a button, and when I click on the button I want to download a file without refreshing the current view. If there is any error I want to show that error in alert. The button’s onClick() event is configured to Download() function.

Here is my code

<button onclick="Download(123);">Download</button>

function Download(fileID) {
       window.location = "/Users/MyController/DownloadFile?fileID="+   fileID;
}

The above function works. I see a download popup window. However what if there is error connecting to url, or there is exception inside the controller on the server. In such case I want to show alert with error message. So I thought of using jQuery ajax where I can handle success & error events. So I change my JavaScript function to use AJAX call as below but it doesn’t work. It makes the call to server, I see controller gets executed. However I don’t see a download popup window.

function Download(fileID) {
    var dataToPost = { fileID: fileID};
    $.ajax({
        type: 'POST',
        data: JSON.stringify(dataToPost),
        url: "/Users/MyController/DownloadFile",
        contentType: 'application/json; charset=utf-8',
        success: function (result) {
            // I don’t want to set window.location here because this event gets fired AFTER server call. So setting it here will make one more server call to download file.
    },
    error: function (xhr, ajaxOptions, thrownError) {       
            // How do I get the exception message here?
    }
})

Controller Code

public ActionResult DownloadFile(int fileID) {
        try {
            var filePath = GetFilePath(fileID);
            var fp = new FilePathResult(filePath, "application/octet-stream");
            fp.FileDownloadName = "test.xlsx";
            return fp;
        } catch (FileNotFoundException ex) {
            throw new Exception("Cound not file requested file.");
        } catch (Exception ex) {
            throw new Exception("There is a problem downloading file");
        }
}

Upvotes: 0

Views: 7187

Answers (1)

dmeglio
dmeglio

Reputation: 2830

Unfortunately, you can't use $.ajax to download a file, it's a limitation of HTML/JavaScript. There are some hacks that involve downloading the file into a hidden iframe and using a cookie to track whether or not it downloaded to simulate AJAX, however. Personally, I use a jQuery plugin, http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/ That web page also gives a very good explanation of what it's doing (using an iframe and cookie). This plugin gives you handlers so you can display a message like "The download has started" when it begins, and also handlers that fire on success and failure. You could certainly implement the hidden iframe logic yourself, I've just found this plugin super easy to use personally.

There is a sample on that page that shows how to set the cookie in MVC as well.

Upvotes: 1

Related Questions