0

I have an ASP.Net MVC application that exports data to an Excel workbook; an .xlsx file.

The workbook is generated correctly on the server and Excel is able to open and display the file if I open it from the output directory (i.e. d:\sites\app\content\exported_data\dataset_2021-12-12.xlsx). This file is 24k in size.

When the workbook is downloaded via HTTP (i.e. http://site.company.com/content/exported_data/dataset_2021-12-12.xlsx), it cannot be opened by Excel. Excel will tell you the file is damaged and if you try to repair the file, that process fails. The downloaded file is 40k.

Server: Windows Server 2016 Data Center (10.0.14393.4704); IIS 10.0.14393.0

Client: Windows 10 (10.0.19041.1052); Chrome 96.0.4664.45

Static content compression is turned off.

What am I missing here?

Update #1 Downloading a .TXT file works just fine.

Update #2 Corruption also fails under IE11 and Edge.

Update #3 Request headers:

GET /content/exported_data/dataset_2021-12-12.xlsx HTTP/1.1
Host: site.company.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: _ga=GA1.2.22470475.1602604311; FWA Device Cookie=c44514ea-30ea-4579-969c-dfaad56002df; rxVisitor=1637946224265ID87N5ET43TH5SI86J0O7BJSLFDBSUIA; dtCookie=v_4_srv_2_sn_029F965CFA2AD25C362FEDB269BCC826_perc_100000_ol_0_mul_1_app-3Ae7bdf245ee5f8b62_1_app-3A65c25f0debc01cd8_1_rcs-3Acss_0; dtSa=-; dtLatC=26; FWA_Session_Cookie=b5427e92-983f-4b5d-82cc-83e2c2c468f7; ASP.NET_SessionId=zdpkziw4w1mtv3qt5bnj4tsi; dtPC=2$558067128_615h-vBVCARAAREUABLAKKHWMVOAUUMAHVUUGV-0e0; rxvt=1638821269230|1638819469230
If-None-Match: "55388354cfead71:0"
If-Modified-Since: Mon, 06 Dec 2021 18:30:22 GMT

Response headers

HTTP/1.1 304 Not Modified
Cache-Control: private
Accept-Ranges: bytes
ETag: "55388354cfead71:0"
Server: Microsoft-IIS/10.0
Set-Cookie: FWA Device Cookie=c44514ea-30ea-4579-969c-dfaad56002df; expires=Sun, 06-Mar-2022 19:45:26 GMT; path=/
Set-Cookie: FWA_Session_Cookie=b5427e92-983f-4b5d-82cc-83e2c2c468f7; expires=Mon, 06-Dec-2021 20:15:26 GMT; path=/
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Mon, 06 Dec 2021 19:45:26 GMT

Update #4 Screen capture of Beyond Compare 4 diff between the downloaded version (40kb) on the left and the server file (24kb) on the right.

Left side is the downloaded file (40kb). Right side is the server file (24kb).

Update #5
I solved the problem, though not the way I wanted to. (I did it in code, not at the server level, I'll detail that )

@BruceZhang-MSFT suggested that I try a different server. Which gave a different result.

The server exhibiting the behavior returns "Microsoft Windows [Version 10.0.14393]" when running ver.exe from the command line.

On another server that doesn't corrupt the Excel files on download, running ver.exe from the command line returns "Microsoft Windows [Version 10.0.17763.2300]".

If I change the controller code and explicitly set the encoding, like below, the Excel files download correctly.

public FilePathResult XlsxDataTable(DataTable table, string reportName)
{
    var rootName = reportName + "_" + DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss");
    var fileName = rootName + ".xlsx";
    var filePath = Path.Combine(Request.MapPath("~/Content/exported_data"), fileName);

    using (XLWorkbook workbook = table.ToXlsx(rootName, filePath))
    {
        var result = new FilePathResult(filePath, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        result.FileDownloadName = fileName;
        Response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1"); // <-- This the new line that fixes the problem
        return result;
    }
}

How do I push this encoding into the OS and IIS? It seems pretty specific to this particular build of Windows Server that I'm stuff with.

amber
  • 149
  • 8
  • Do a diff of the raw file and the downloaded one, and post those results as well. – mfinni Dec 06 '21 at 20:42
  • @mfinni Screen capture of the diff. – amber Dec 06 '21 at 21:42
  • What's your MIME type in IIS for XSLX, for this site? Taking a look at one of my IIS servers, it's configured for "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" – mfinni Dec 07 '21 at 00:46
  • Saving the file as ANSI probably isn't good. – Greg Askew Dec 07 '21 at 00:49
  • @mfinni That was one of the first things I thought of, maybe the server didn't have it configured. I confirmed the server is configured correctly. – amber Dec 07 '21 at 15:33

1 Answers1

0

This answer tells you how to set the content encoding for a .NET app

Copying here for longevity

The content encoding is set in the Machine.config file when the .NET Framework is installed. You can edit this file which will affect the response encoding of all ASP.NET sites, or you can override it on a per-site basis using the element in each site's Web.config file.

Credit to @markbell

mfinni
  • 36,144
  • 4
  • 53
  • 86