ASP.NET MVC kullanıcıya geri bir veritabanında depolanan dosyaları gönderme ile ilgili bir sorunla karşılaşıyorum. Ne istediğim, bir dosyayı görüntülemek ve tarayıcıya gönderilen mime türünün nasıl ele alınacağını belirlemesine ve diğeri de indirmeye zorlamak için iki bağlantıyı listeleyen bir görünümdür.
Adında bir dosyayı görüntülemeyi seçersem SomeRandomFile.bak
ve tarayıcının bu tür dosyaları açmak için ilişkili bir programı yoksa, indirme davranışını varsayılan olarak onunla ilgili bir sorunum yok. Ancak, adlı bir dosyayı görüntülemeyi seçersem SomeRandomFile.pdf
veya SomeRandomFile.jpg
dosyanın açılmasını istiyorum. Ancak dosya türünden bağımsız olarak bir indirme istemini zorlayabilmem için bir indirme bağlantısını yanda tutmak istiyorum. Bu mantıklı mı?
Denedim FileStreamResult
ve çoğu dosya için çalışıyor, yapıcısı varsayılan olarak bir dosya adını kabul etmiyor, bu nedenle bilinmeyen dosyalara URL'ye (içerik türüne göre verilecek uzantıyı bilmeyen) bir dosya adı atanıyor. Dosya adını belirterek zorlarsam, tarayıcının dosyayı doğrudan açma yeteneğini kaybederim ve bir indirme istemi alırım. Başka kimse bununla karşılaştı mı?
Bunlar şimdiye kadar denediklerimin örnekleri.
//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};
Herhangi bir öneri?
GÜNCELLEME:
Bu sorular birçok insanla bir akor vuruyor gibi görünüyor, bu yüzden bir güncelleme yayınlayacağımı düşündüm. Oskar'ın uluslararası karakterlerle ilgili eklediği aşağıdaki cevap ile ilgili uyarı tamamen geçerlidir ve ContentDisposition
sınıfı kullandığım için birkaç kez vurdum . O zamandan beri bunu düzeltmek için uygulamamı güncelledim. Aşağıdaki kod bir ASP.NET Core (Full Framework) uygulamasında bu sorunun en son enkarnasyonundan olsa da, System.Net.Http.Headers.ContentDispositionHeaderValue
sınıfı kullandığım için eski bir MVC uygulamasında da minimum değişikliklerle çalışmalıdır .
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
}