简体   繁体   中英

File download problem - ASP.NET MVC application

I have two controller actions and js in a view in an ASP.NET MVC application to generate and download an Excel file. All relevant code is shown here:

public ActionResult GetExcel()
{
    string handle = Guid.NewGuid().ToString();

    using (MemoryStream MemoryStream = new MemoryStream())
    {
        //GetExcelData returns an OfficeOpenXml.ExcelPackage object
        GetExcelData().SaveAs(MemoryStream);
        MemoryStream.Position = 0;
        TempData[handle] = MemoryStream.ToArray();
    }

    return new JsonResult()
    {
        Data = new { FileGuid = handle, FileName = "FileName" + DateTime.Now.ToString() + ".xlsx" }
    };
}

public virtual ActionResult Download(string fileGuid, string fileName)
{
    if (TempData[fileGuid] != null)
    {
        byte[] data = TempData[fileGuid] as byte[];
        return File(data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
    }
    else
    {
        return new EmptyResult();
    }
}

$.ajax({
  url: '@Url.Action("GetExcel", "Products")',
  type: 'POST',  
}).done(function (data) {  
  window.location = '@Url.Action("Download", "Products")' + '?fileGuid=' + data.FileGuid + '&filename=' + data.FileName;
});

My problem is that this code results on an inconsistent behavior.

Sometimes it works as expected and I get to be prompted with a download file screen, but sometimes it results in a blank page with the path to the file as browser's url.

在此处输入图像描述

One thing I noticed is that when the problem happens, the type of the document on browser's.network tab is plain, not application/vnd.openxmlformats-officedocument.spreadsheetml.sheet , as it would be expected.

Another point is that this happens just when the application is on the IIS on the server. This does not happen locally in development environment.

Also, apparently, is does not seems to be related to file size, since it is happening with small and large data sets.

I have used EPPlus library to generate and download an excel file. Install EPPLUS from Manage Nuget Packages. Make sure if you use the library then use it under NonCommercial LicenseContext as ExcelPackage.LicenseContext = LicenseContext.NonCommercial

If you wanna generate directly through anchor tag link "@Url.Action("Test","Test")" then use the following code.

 using (ExcelPackage excel = new ExcelPackage())
    {
          var stream = new MemoryStream();
          ExcelWorksheet worksheet = 
          excelPackage.Workbook.Worksheets.Add("TestWork");
        //add values in your worksheet cells you can also loop through it like  
        //worksheet.Cells[i + 2, 1].Value where i is an index starting from 0 and 1 is the column index [rowIndex,columnIndex]
         worksheet.Cells["A1"].Value = "Date";
         worksheet.Cells["A2"].Value = "10-10-2021";
        //add table styling
        int firstRow = 1;
        int lastRow = worksheet.Dimension.End.Row;
        int firstColumn = 1;
        int lastColumn = worksheet.Dimension.End.Column;
        ExcelRange rg = worksheet.Cells[firstRow, firstColumn, lastRow, lastColumn];
        string tableName = "Table1";
        ExcelTable tab = worksheet.Tables.Add(rg, tableName);
        tab.TableStyle = TableStyles.Medium2;
        excel.Save();
        byte[] bin = excelPackage.GetAsByteArray();
        Response.ClearHeaders();
        Response.Clear();
        Response.Buffer = true;
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-length", bin.Length.ToString());
        this.Response.AddHeader("content-disposition", string.Format("attachment;  filename={0}", YourFileName));
        Response.OutputStream.Write(bin, 0, bin.Length);
        Response.Flush();
    }

If you're sending an ajax request then code will be same till excel.Save(); just change the return type of the response such as JsonResult

 var fileObject = File(excel.GetAsByteArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx");
 return new JsonResult()
                            {
                                Data = fileObject,
                                ContentType = "application/json;  charset=utf-8",
                                ContentEncoding = Encoding.UTF8,
                                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                                MaxJsonLength = Int32.MaxValue
                            };

The issue that you are experiencing might be related to the file size just try by wrapping the response in JSON with max length

 return new JsonResult()
                        {
                            Data = fileObject,
                            ContentType = "application/json;  charset=utf-8",
                            ContentEncoding = Encoding.UTF8,
                            JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                            MaxJsonLength = Int32.MaxValue
                        };

Ajax Request to download the file object from the JSONResult response returned by the server in the success function

 $.ajax({
            type: 'POST',
            url: '',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (response) {
                var bytes = new Uint8Array(response.FileContents);
                var blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
                var downloadUrl = URL.createObjectURL(blob);
                var a = document.createElement("a");
                a.href = downloadUrl;         
                a.download = "Filename.xlsx";
                document.body.appendChild(a);
                a.click();
            },
            error: function (err) {
                alert(err);
            },
            cache: false
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM