У мене виникає проблема з поверненням файлів, що зберігаються в базі даних, назад користувачеві в ASP.NET MVC. Я хочу - це перегляд із переліком двох посилань, одне для перегляду файлу та дозвол міметипу, надісланому браузеру, визначає, яким чином слід обробляти, а інший для примусового завантаження.
Якщо я вирішую переглянути файл, який називається, 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
}