2

How to download a file using Ajax in MVC. If no data to generate file then show error label. I'm trying using action result method which returns File. I can download file . but don't want to refresh the page if no file to download. My code is like 

public ActionResult Excel(MyViewModel model)

{

    var result = // DB call to get data

    if (no data)
    {
        return **something**
    }
    else
    {
        byte[] excelContent =//passing result to my method( returns xls file in byte)

        return File(
                    excelContent, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                    reportName + " Report " + startDate + " - " + endDate + ".xlsx");
    }
}

What should I return for something For now I'm returning emptyResult for something hence I got blank page if no data. Ajax doesn't support file download. This code works if I submit the form and there is data. Suggest something in which page will not get refresh and both task get achieved. 1. File download if data 2. Show error label if no data

Dev
  • 21
  • 1
  • 3

3 Answers3

0
  1. If get file using Ajax then best way to create API
  2. Function return type is FileResult

    var exportToExcel = function (inputData, fileName) {
    var path = "url";
    var form = $("<form></form>");
    form.attr("enctype", "application/x-www-form-urlencoded");
    form.attr("method", "post");
    form.attr("action", path);
    form.attr("accept-charset", "UTF-8");
    
    var field = $("<input></input>");
    field.attr("type", "hidden");
    field.attr("name", "data");
    field.attr("value", escape(JSON.stringify(inputData)));
    
    form.append(field);
    var field2 = $("<input></input>");
    
    field2.attr("name", "fileName");
    field2.attr("value", fileName);
    form.append(field2);
    $(document.body).append(form);
    form.submit().remove();
    

    };

    var downloadFile = function (inputData) { // checkFileHasResult is ajax call result if true or false checkFileHasResult(inputData).then(function (hasFile) { if (hasFile === true) { // give file name with extension exportToExcel(inputData, "asdfasdf.csv"); } }); };

0

Doing a quick search in Google, brought up quite a few results, as this question.

In JQuery, you could just point you 'window.location' to your action method in the controller, that returns a FileResult. This will download the file for you.

I would suggest, you return message to an ajax call, stating whether your download was successful or not, and then you can set some sort of text on the front end to notify the user that this process was unsuccessful.

Here is how I would have accomplished this. You can tweak it to work for you. Here is an example of the controller methods.

[HttpGet]
public JsonResult ExportCollection()
{
    //Build your excel file, and save it to disk somewhere on server.
    //you can also save it in session, depending on size
    //Build up response Messages based on success or not

    //return json object with your file path
    return Json(new { responseMessage = responseMessage }, JsonRequestBehavior.AllowGet);
}

public ActionResult Download(string fileName)
{
    return File(model.FilePath, "application/vnd.ms-excel", fileName);
}

And then, call these actions from client side using JQuery and an Ajax call.

 $(document).on("click", "#YourButton", function () {
        var url = "/YourController/ExportCollection/"

        $("#responseText").text("We're getting things ready. Please wait...");
        $('#loadingImage').show();

        $.ajax({
            url: url,
            type: "get",
            success: function (responseMessage) {
                patientCollectionExportSuccess(responseMessage);
            }
        });
    })

//Function responsible for exporting
function patientCollectionExportSuccess(dataReceived) {
    var respMessage = dataReceived.responseMessage;

    if (respMessage != null) {
        if (respMessage != "Error: Not Exported.") {

            $("#responseText").text("Download completed.");
            $('#loadingImage').hide();

            //set window.location to redirect to FileResult, which will download file
            window.location = '/PatientListingQuery/Download?fileName=' + respMessage ;
        }
        else {
            $("#responseText").text("Download unsuccessful.");
            $('#loadingImage').hide();

            $("#responseText").text(dataReceived.responseMessage);
        }

    }
}
Community
  • 1
  • 1
  • is there any alternative instead of saving file ? – Dev Feb 25 '16 at 05:12
  • You can save the file in TempData, for example. But when the user refreshes the page for whatever reason, the file, I believe, would be gone. Might be better to save to disk, and once downloaded, you can remove the file from disk again. –  Feb 25 '16 at 05:23
0

Thanks guys

I got solution It works for me smoothly ....

my form action is pointing to another method, so updated action before submitting the form. and after file download, i'm setting it to old form action.

$(document).ready(function () {
    $('#excel-button').on('click', function () {            
        $.ajax({
            url: '/MyController/IsData',
            type: 'POST',
            data: $("#myForm").serialize(),
            success: function (response) { 
                if (response == "True") {
                    var oldUrl="";
                    var form1 = $('#myForm');

                    var frm = document.getElementById('myForm') || null;
                    if (frm) {
                          oldUrl = frm.action; 
                        frm.action = '/MyController/GenerateExcel';
                    }

                    form1.submit(); 
                    frm.action = oldUrl; 
                    $('.error-Message').hide(); 

                }                    else {                         

                    $('.error-Message').show(); 

                }
            }
    });
    });
Dev
  • 21
  • 1
  • 3