Рейтинг:0

IIS 10 повреждает файл Excel при загрузке

флаг bd

У меня есть приложение ASP.Net MVC, которое экспортирует данные в книгу Excel; файл .xlsx.

Рабочая книга правильно создается на сервере, и Excel может открыть и отобразить файл, если я открою его из выходного каталога (например, d:\sites\app\content\exported_data\dataset_2021-12-12.xlsx). Этот файл имеет размер 24k.

Когда книга загружается через HTTP (т. http://site.company.com/content/exported_data/dataset_2021-12-12.xlsx), его нельзя открыть в Excel.Excel сообщит вам, что файл поврежден, и если вы попытаетесь восстановить файл, этот процесс завершится ошибкой. Скачанный файл весит 40k.

Сервер: Центр обработки данных Windows Server 2016 (10.0.14393.4704); ИИС 10.0.14393.0

Клиент: Windows 10 (10.0.19041.1052); Хром 96.0.4664.45

Сжатие статического контента отключено.

Что мне здесь не хватает?

Обновление №1 Загрузка файла .TXT работает нормально.

Обновление №2 Коррупция также не работает в IE11 и Edge.

Обновление №3 Заголовки запроса:

ПОЛУЧИТЬ /content/exported_data/dataset_2021-12-12.xlsx HTTP/1.1
Хост: site.company.com
Соединение: Keep-alive
Обновить-небезопасные-запросы: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, например Gecko) Chrome/96.0.4664.45 Safari/537.36
Принять: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3; р=0,9
Accept-Encoding: gzip, deflate
Принять-Язык: en-US,en;q=0.9
Файл cookie: _ga=GA1.2.22470475.1602604311; Файл cookie устройства FWA=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; дтСа=-; dtLatC=26; FWA_Session_Cookie=b5427e92-983f-4b5d-82cc-83e2c2c468f7; ASP.NET_SessionId=zdpkziw4w1mtv3qt5bnj4tsi; dtPC=2$558067128_615h-vBVCARAAREUABLAKKHWMVOAUUMAHVUUGV-0e0; гксвт=1638821269230|1638819469230
Если-Нет-совпадения: "55388354cfead71:0"
If-Modified-Since: понедельник, 06 декабря 2021 г., 18:30:22 по Гринвичу

Заголовки ответа

HTTP/1.1 304 Не изменено
Кэш-Контроль: частный
Допустимые диапазоны: байты
ETag: "55388354cfead71:0"
Сервер: Microsoft-IIS/10.0
Set-Cookie: Cookie устройства FWA=c44514ea-30ea-4579-969c-dfaad56002df; expires=Вс, 06 марта 2022 г., 19:45:26 по Гринвичу; путь=/
Set-Cookie: FWA_Session_Cookie=b5427e92-983f-4b5d-82cc-83e2c2c468f7; expires=пн, 06 декабря 2021 г., 20:15:26 по Гринвичу; путь=/
Постоянная аутентификация: правда
X-Powered-By: ASP.NET
Дата: пн, 06 декабря 2021 г., 19:45:26 по Гринвичу

Обновление №4 Скриншот Beyond Compare 4: разница между загруженной версией (40 КБ) слева и серверным файлом (24 КБ) справа.

Слева — загруженный файл (40кб). Справа находится файл сервера (24 КБ).

Обновление №5
Я решил проблему, хотя и не так, как хотел. (Я сделал это в коде, а не на уровне сервера, я подробно расскажу об этом)

@BruceZhang-MSFT предложил попробовать другой сервер. Что дало другой результат.

Сервер, демонстрирующий поведение, возвращается «Майкрософт Windows [версия 10.0.14393]» при запуске ver.exe из командной строки.

На другом сервере, который не повреждает файлы Excel при загрузке, запуск ver.exe из командной строки возвращает «Майкрософт Windows [версия 10.0.17763.2300]».

Если я изменю код контроллера и явно установлю кодировку, как показано ниже, файлы Excel загружаются правильно.

public FilePathResult XlsxDataTable (таблица DataTable, строка reportName)
{
    var rootName = reportName + "_" + DateTime.Now.ToString("гггг-ММ-дд_ЧЧ.мм.сс");
    var fileName = rootName + ".xlsx";
    var filePath = Path.Combine(Request.MapPath("~/Content/exported_data"), имя_файла);

    используя (книга XLWorkbook = table.ToXlsx(rootName, filePath))
    {
        var result = new FilePathResult(filePath, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        результат.ИмяЗагрузкиФайла = ИмяФайла;
        Response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1"); // <-- Это новая строка, исправляющая проблему
        вернуть результат;
    }
}

Как передать эту кодировку в ОС и IIS? Это кажется довольно специфичным для этой конкретной сборки Windows Server, с которой я работаю.

mfinni avatar
флаг cn
Сделайте diff исходного файла и скачанного, и опубликуйте эти результаты.
флаг bd
@mfinni Снимок экрана diff.
mfinni avatar
флаг cn
Какой у вас тип MIME в IIS для XSLX для этого сайта? Взглянув на один из моих серверов IIS, он настроен на «application/vnd.openxmlformats-officedocument.spreadsheetml.sheet».
флаг cn
Сохранение файла как ANSI, вероятно, не очень хорошо.
флаг bd
@mfinni Это было одной из первых вещей, о которых я подумал, может быть, сервер не был настроен. Я подтвердил, что сервер настроен правильно.
Рейтинг:0
флаг cn

Этот ответ рассказывает вам, как установить кодировку содержимого для приложения .NET.

Копирую сюда для долголетия

Кодировка содержимого задается в файле Machine.config при установке .NET Framework. Вы можете отредактировать этот файл, который повлияет на кодировку ответов всех сайтов ASP.NET, или вы можете переопределить его для каждого сайта, используя элемент в файле Web.config каждого сайта.

Кредит для @маркбелл

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.