0

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

1 Answer 1

1

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.

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

6 Comments

Thanks. I will certainly take a look at it. we are also using kendo UI, I was trying to avoid too many jQuery plugins
If you're using kendo have you looked at demos.telerik.com/kendo-ui/upload/async ? I should also clarify, when I said it wasn't possible with html, it is possible in html5
we are using html5 however it needs to be compatible with IE8. kendo link you provided is for upload,& im looking for download
Somehow when I typed my comment I forgot it was for download. Then yeah, the hidden frame is the only way to simulate it unless you want to introduce something like a Flash swf to do the download.
Thanks @dman2306 for your help. Downloading a file is very common scenario, not sure why it needs to be so difficult :( with MVC
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.