Score:0

IIS 10 corrupts Excel file on download

bd flag

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.

mfinni avatar
cn flag
Do a diff of the raw file and the downloaded one, and post those results as well.
bd flag
@mfinni Screen capture of the diff.
mfinni avatar
cn flag
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"
cn flag
Saving the file as ANSI probably isn't good.
bd flag
@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.
Score:0
cn flag

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

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.