У нас есть несколько файлов, хранящихся в базе данных sql. В форме ASP.NET MVC3 мы отображаем 2 ссылки:
Просмотр этого файла | Скачать этот файл
Эти ссылки ведут на соответствующие методы действий. Загрузка работает как положено - при нажатии на ссылку в браузере открывается диалоговое окно сохранения. Тем не менее, отображение заставляет дубликаты заголовков Content-Disposition отправлять в браузер, что приводит к ошибке в Chrome и пустой странице в Firefox.
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
Response.AddHeader("Content-Disposition",
string.Format("inline; filename={0}", file.Name));
return File(file.Content, file.MimeType, file.Name);
}
}
[ActionName("download-file")]
public virtual ActionResult DownloadFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
return File(file.Content, file.MimeType, file.Name);
}
}
Вот 2 заголовка, отправленных в браузер для действия отображения:
Content-Disposition: inline; filename=name-of-my-file.pdf
Content-Disposition: attachment; filename="name-of-my-file.pdf"
Я попытался изменить свой настраиваемый заголовок размещения содержимого, чтобы обернуть имя файла в двойные кавычки, но он все равно отправил 2 заголовка в браузер. Я также попытался удалить заголовок Content-Disposition перед добавлением пользовательского, но похоже, что заголовок вложения добавляется после того, как FileContentResult возвращается.
Этот код используется для работы. Я провел тест только вчера и заметил, что он больше не работает в Chrome или Firefox. Это может быть связано с обновлениями в браузерах. IE8 и Safari по-прежнему открывают файл правильно.
Обновление
Еще раз спасибо, Дарин, ты прав. Мы действительно использовали этот подход, потому что другой вопрос, на который вы ответили .
Немного больше информации о том, как это в конечном итоге было решено с нашей стороны, у нас есть собственный маршрут для ссылки на файл дисплея:
context.MapRoute(null,
"path/to/display-file-attachment/{fileId}/{fileName}",
new
{
area = "AreaName",
controller = "ControllerName",
action = "DisplayFile",
}
);
Гиперссылка на странице передает имя файла методу действия через параметр маршрута, поэтому оно уже является частью URL. Таким образом, нам не нужно было добавлять пользовательский заголовок размещения контента, чтобы имя файла совпадало с именем системы, когда пользователь решил загрузить его (нажав на значок сохранения в браузере PDF Viewer). Итак, мы просто использовали это:
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
// no custom content-disposition header, and no 3rd fileName argument
return File(file.Content, file.MimeType);
}
}