Потоковый PDF не удается - файл не найден
Этим утром я провел некоторое время, пытаясь помочь коллеге с странной ошибкой, которая в настоящее время ставит нас в тупик. Сценарий заключается в том, что у нас есть система в разработке, которая позволяет пользователям прикреплять файлы PDF к записи данных. Система использует сервис для хранения и извлечения файлов с сервера и сохраняет идентификатор в таблице вложений, чтобы указать, какие файлы принадлежат каким записям.
Затем на двух разных страницах приложения у нас есть сетка, в которой отображается список вложений для записи. В сетке находятся кнопки ссылок, которые позволяют пользователю открыть данное вложение. Кнопка ссылки вызывает событие команды, передавая идентификатор вложения в качестве аргумента. В обработчике события команды мы получаем идентификатор из аргумента, используем его для извлечения вложения из службы в виде байтового массива, а затем перезаписываем объект ответа для возврата вложения. Вот код:
byte[] byteFile = DataHandler.GetAttachmentDocument(selectedAttachmentID);
if (DataHandler.sErrorMsg != "")
{//Error trying to retrieve file...
this.DisplayMessageBox(DataHandler.sErrorMsg);
}
else
{//File retrieved...
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=" + lblAttachmentName.Text);
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(byteFile);
Response.Flush();
Response.Close();
Response.End();
}
Теперь этот точно такой же код отлично работает на одной странице и не работает на другой. В обоих случаях, когда нажата кнопка и отображается диалоговое окно загрузки, нажмите кнопку "Открыть", и откроется окно Adobe Reader. На рабочей странице в окне читателя отображается запрошенный документ, но на другой странице из окна читателя мы получаем сообщение об ошибке: There was an error opening this document. This file cannot be found.
Запустив в отладчике, мы можем пройти и увидеть, что мы получаем одинаковое количество байтов в byteFile, и что мы проходим полный метод без ошибок.
Мы немного погуглили по этому поводу и попробовали несколько вариантов этого кода, но безуспешно. Несколько вещей, которые я знаю, мы пытались изменить тип контента на поток октетов, добавить длину контента в заголовок, изменить буфер на false, удалить атрибут размещения контента. Единственная заметная разница заключалась в удалении атрибута размещения содержимого, в этом случае документ отображался, но отображался в исходном окне, а не в отдельном окне Adobe Reader. Еще одна идея, которая была предложена, но пока не опробована, заключается в том, чтобы извлечь сетку и связанную логику из веб-элемента управления, который затем можно будет повторно использовать на обеих страницах. Любые другие предложения?
2 ответа
Хотя нам никогда не удавалось точно определить причину проблемы, мы решили, что она, по крайней мере, в некоторой степени зависит от пользователя / компьютера. Таким образом, наша лучшая догадка - это какой-то странный конфликт или проблема с кэшированием на стороне клиента.
В конечном итоге мы разработали пустую страницу, которая принимает идентификатор и имя вложения в строке запроса, выполняет некоторые проверки безопасности, а затем возвращает запрошенное вложение. Это дало нам один, многократно используемый модуль, содержащий наш код поиска вложений.
Затем мы перешли на страницы, которые обслуживают вложения, и изменили наши шаблоны сетки с кнопок ссылок с аргументами команд на гиперссылки с URL-адресом навигации, привязанным к пути новой страницы + аргументы строки запроса и целью _blank
,
Конечным результатом является то, что мы устранили ошибки без существенных изменений в структуре страницы, сохранили желаемый интерфейс для конечного пользователя и получили структуру кода, которую будет проще поддерживать.
Спасибо Леону за подсказку. Хотя это не решило проблему, это помогло нам немного очистить наш код.
Не используйте Response.Close() и Response.End(). Flush() достаточно.