Как избежать дублирования заголовков размещения содержимого с помощью MVC3 FileContentResult?

У нас есть файлы, хранящиеся в базе данных 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 заголовка, отправленных браузеру для действия display:

Content-Disposition: inline; filename=name-of-my-file.pdf
Content-Disposition: attachment; filename="name-of-my-file.pdf"

Я попытался изменить свой собственный заголовок Content-Disposition, чтобы заключить имя файла в двойные кавычки, но браузер все равно отправил 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-файлов). Итак, мы просто использовали это:

[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);
    }
}

12
задан Community 23 May 2017 в 11:54
поделиться