Я столкнулся с проблемой отправки файлов, хранящихся в базе данных, обратно пользователю в ASP.NET MVC. То, что я хочу, - это представление, в котором перечислены две ссылки: одна для просмотра файла, и пусть mimetype, отправляемый в браузер, определяет, как он должен обрабатываться, а другая для принудительной загрузки.
Если я выбрал просмотр файла с именем, SomeRandomFile.bak
а в браузере нет соответствующей программы для открытия файлов этого типа, у меня не возникнет проблем с его настройками по умолчанию при загрузке. Однако, если я решу просмотреть файл с именем SomeRandomFile.pdf
или SomeRandomFile.jpg
я хочу, чтобы файл просто открылся. Но я также хочу оставить ссылку для скачивания в стороне, чтобы можно было принудительно вызвать приглашение к загрузке независимо от типа файла. Имеет ли это смысл?
Я пробовал, FileStreamResult
и он работает для большинства файлов, его конструктор не принимает имя файла по умолчанию, поэтому неизвестным файлам присваивается имя файла на основе URL-адреса (который не знает расширение для предоставления на основе типа содержимого). Если я задаю имя файла, указав его, я теряю способность браузера открывать файл напрямую и получаю приглашение на загрузку. кто-нибудь еще сталкивался с этим?
Это примеры того, что я пробовал до сих пор.
//Gives me a download prompt.
return File(document.Data, document.ContentType, document.Name);
//Opens if it is a known extension type, downloads otherwise (download has bogus name and missing extension)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType);
//Gives me a download prompt (lose the ability to open by default if known type)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType) {FileDownloadName = document.Name};
Какие-либо предложения?
ОБНОВЛЕНИЕ:
Эти вопросы, кажется, вызывают отклик у многих людей, поэтому я решил опубликовать обновление. Предупреждение о принятом ответе ниже, которое было добавлено Оскаром в отношении международных символов, является полностью действительным, и я ударил его несколько раз из-за использования ContentDisposition
класса. С тех пор я обновил свою реализацию, чтобы исправить это. Хотя приведенный ниже код взят из моего последнего воплощения этой проблемы в приложении ASP.NET Core (Full Framework), он должен работать с минимальными изменениями и в более старом приложении MVC, так как я использую этот System.Net.Http.Headers.ContentDispositionHeaderValue
класс.
using System.Net.Http.Headers;
public IActionResult Download()
{
Document document = ... //Obtain document from database context
//"attachment" means always prompt the user to download
//"inline" means let the browser try and handle it
var cd = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = document.FileName
};
Response.Headers.Add(HeaderNames.ContentDisposition, cd.ToString());
return File(document.Data, document.ContentType);
}
// an entity class for the document in my database
public class Document
{
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Data { get; set; }
//Other properties left out for brevity
}