0

I want to start a download of a file from the (local in my case) web server when an user clicks on a button. When the user clicks on the button, a C# method exports a database in an XLS file and the download should start. The first part works perfectly, but the download does not start.

This is the JS function that starts when the users uses the button:

function ExportXLS(t) 
{
    var date=$('#dateForm').serialize();

    $.ajax({
        cache: false,
        type: "POST",
        url: '@Url.Action("exportToXLS", "Connection")',
        data:
        {
            'type': t,
            'date': date
            },
        success: function () {
            alert("Great");
        },
        error: function () {
            alert("Fail");

        }
    });
}

And these are the c# methods:

//Controller #1
[HttpPost]
public void exportToXLS(int type, string date)
{
    FileController fc = new FileController();
    string fileName = Server.MapPath("Common").Replace("\\Connection", "") + @"\XLS\NewFile.xls"; //C:\Users\MyUser\Documents\Projects\Name\Name\Common\XLS\NewFile.xls
    switch (type)
    {
        case 1: exportToXLS1(fileName, date); break;
        case 2: exportToXLS2(fileName, date); break;
    }  
    fc.DownloadDirectFromName(fileName);
}

//FileController
[Authorize]
public FileResult DownloadDirectFromName(string fileName)
{
    try
    {
        if (fileName != null && fileName != "")
        {
            FileInfo path = new FileInfo(fileName);

            // Checking if file exists
            if (path.Exists)
            {

                string downloadName = Path.GetFileName(fileName);
                string contentType = Path.GetExtension(fileName);

                Response.ClearContent();
                Response.AddHeader("Content-Length", path.Length.ToString());
                Response.AddHeader("Content-Type", contentType);
                Response.AddHeader("Content-Disposition", "attachment; filename=\"" + downloadName + "\"");
                Response.Flush();// do not add anymore headers after this...
                Response.TransmitFile(fileName);
                Response.End();

                /*byte[] buffer = new byte[4 * 1024]; // 4kb is a good for network chunk

                using (FileStream fs = path.OpenRead())
                {
                    int count = 0;
                    while ((count = fs.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        if (!Response.IsClientConnected)
                        {
                            // network connection broke for some reason..
                            break;
                        }
                        Response.OutputStream.Write(buffer, 0, count);
                        Response.Flush(); // this will prevent buffering...
                    }
                }*/
            }
        }
    }
    catch (Exception ex)
    {
        WebAppSettings.LogErr("Download file: " + ex);
    }

    return null;
}

My problem is that the file is created, but the download does not start. I always get an exception saying that Response is null. Why? Could it be that the path is wrong? Is the method incomplete? i searched everywhere, but the way to download a file should be this one.

EDIT: I made a small project to try this thing, but I have a problem.

//
//JS
//
function testDownload()
    {
        $.ajax({
            cache: false,
            type: "POST",
            url: '@Url.Action("myTest", "Home")',
            success: function (result) {
                //window.location = result.location;
                alert(result.location);
            },
            error: function () {
                alert("Failed.");
            }
        });
    }

//
//C#
//
[HttpPost]
        public ActionResult myProva()
        {
            byte[] fileBytes = System.IO.File.ReadAllBytes(@"C:\Users\MyUser\Desktop\MyFile.txt");
            string fileName = "MyFile.ext";
            Response.Headers.Add("Content-Disposition", $"attachment; filename=\"{fileName}\"");
            return File(fileBytes, "application/txt", fileName);
        }

If I write alert(result) I can see the content of the file, but if I use the commented line, nothing happen (result.location is undefined). Why? And can the download start without being redirected to a new page?

  • Possible duplicate of [Download file of any type in Asp.Net MVC using FileResult?](https://stackoverflow.com/questions/3604562/download-file-of-any-type-in-asp-net-mvc-using-fileresult) – maccettura Aug 15 '17 at 14:29
  • You can not make a background request to trigger a download. The response will only land β€œin” your JS code, it does not get passed to the UI from there. – CBroe Aug 15 '17 at 14:29

0 Answers0