Saya mengalami masalah pengiriman file yang disimpan dalam database kembali ke pengguna di ASP.NET MVC. Yang saya inginkan adalah tampilan yang mencantumkan dua tautan, satu untuk melihat file dan membiarkan mimetype yang dikirim ke browser menentukan cara penanganannya, dan yang lainnya untuk memaksa unduhan.
Jika saya memilih untuk melihat file yang dipanggil SomeRandomFile.bak
dan browser tidak memiliki program yang terkait untuk membuka file jenis ini, maka saya tidak punya masalah dengan itu default ke perilaku unduhan. Namun, jika saya memilih untuk melihat file yang dipanggil SomeRandomFile.pdf
atau SomeRandomFile.jpg
saya ingin file tersebut terbuka. Tapi saya juga ingin menjaga tautan unduhan agar tidak bisa memaksa permintaan unduhan terlepas dari jenis file. Apakah ini masuk akal?
Saya telah mencoba FileStreamResult
dan berfungsi untuk sebagian besar file, konstruktornya tidak menerima nama file secara default, jadi file yang tidak dikenal diberi nama file berdasarkan URL (yang tidak tahu ekstensi untuk diberikan berdasarkan tipe konten). Jika saya memaksakan nama file dengan menetapkannya, saya kehilangan kemampuan browser untuk membuka file secara langsung dan saya mendapatkan prompt unduhan. Adakah orang lain yang mengalami ini?
Ini adalah contoh dari apa yang saya coba sejauh ini.
//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};
Ada saran?
UPDATE:
Pertanyaan-pertanyaan ini tampaknya cocok dengan banyak orang, jadi saya pikir saya akan memposting pembaruan. Peringatan pada jawaban yang diterima di bawah ini yang ditambahkan oleh Oskar mengenai karakter internasional benar-benar valid, dan saya telah memukulnya beberapa kali karena menggunakan ContentDisposition
kelas. Saya telah memperbarui implementasi saya untuk memperbaikinya. Sementara kode di bawah ini berasal dari inkarnasi terbaru saya tentang masalah ini dalam aplikasi ASP.NET Core (Kerangka Penuh), itu harus bekerja dengan perubahan minimal dalam aplikasi MVC lama juga karena saya menggunakan System.Net.Http.Headers.ContentDispositionHeaderValue
kelas.
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
}
sumber
Inline = true
pastikan TIDAK untuk menggunakan kelebihan 3-paramFile()
yang menjadikan nama-file sebagai param ke-3. Ini akan berfungsi di IE, tetapi Chrome akan melaporkan header duplikat dan menolak untuk menyajikan gambar.Saya mengalami masalah dengan jawaban yang diterima karena tidak ada tipe yang mengisyaratkan pada variabel "dokumen":
var document = ...
Jadi saya memposting apa yang berhasil bagi saya sebagai alternatif jika ada orang lain yang mengalami masalah.sumber
AppDomain.CurrentDomain.BaseDirectory
adalahSystem.Web.HttpContext.Current.Server.MapPath("~")
, ini dapat bekerja lebih baik pada server nyata dibandingkan dengan mesin lokal.Jawaban Darin Dimitrov benar. Hanya tambahan:
Response.AppendHeader("Content-Disposition", cd.ToString());
dapat menyebabkan browser gagal membuat file jika respons Anda sudah berisi tajuk "Content-Disposition". Dalam hal ini, Anda mungkin ingin menggunakan:sumber
pdf
file, jika saya menetapkan tipe konten sebagaiSystem.Net.Mime.MediaTypeNames.Application.Octet
, itu akan memaksa unduhan bahkan ketika saya aturInline = true
, tetapi jika saya aturResponse.ContentType = MimeMapping.GetMimeMapping(filePath)
, yaituapplication/pdf
, ia dapat membuka dengan benar daripada mengunduhResponse.Headers.Add
membutuhkan mode pipa terintegrasi IIS. Selain itu, bahkan jika kumpulan aplikasi ditetapkan sebagai terintegrasi, itu akan menimbulkan pengecualian. Larutan. GunakanResponse.AddHeader
. Lihat utas SO: stackoverflow.com/questions/22313167/…Untuk melihat file (txt misalnya):
Untuk mengunduh file (txt misalnya):
Catatan: untuk mengunduh file kita harus melewati argumen fileDownloadName
sumber
Inline
properti pada Content-Disposition memungkinkan saya untuk memisahkan kemampuan pengaturan nama file dari perilaku memaksa unduhan atau tidak.Saya yakin jawaban ini lebih bersih, (berdasarkan https://stackoverflow.com/a/3007668/550975 )
sumber
application/octet-stream
dan itu masih menyebabkan file untuk diunduh daripada ditampilkan, dan tampaknya kompatibel.FileVirtualPath -> Research \ Global Office Review.pdf
sumber
Kode di bawah ini berfungsi untuk saya untuk mendapatkan file pdf dari layanan API dan menanggapinya ke browser - semoga membantu;
sumber
Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider
Metode tindakan perlu mengembalikan FileResult dengan aliran, byte [], atau jalur virtual file. Anda juga perlu mengetahui tipe konten dari file yang sedang diunduh. Berikut adalah contoh metode utilitas (cepat / kotor). Contoh tautan video Cara mengunduh file menggunakan asp.net core
sumber
Jika, seperti saya, Anda telah sampai ke topik ini melalui komponen Razor saat Anda mempelajari Blazor, maka Anda akan perlu berpikir lebih banyak di luar kotak untuk menyelesaikan masalah ini. Agak seperti ladang ranjau jika (juga seperti saya) Blazor adalah forray pertama Anda ke dunia tipe-MVC, karena dokumentasi tidak membantu untuk tugas-tugas 'kasar' seperti itu.
Jadi, pada saat penulisan, Anda tidak dapat mencapai ini menggunakan vanilla Blazor / Razor tanpa menyematkan pengontrol MVC untuk menangani bagian pengunduhan file, contohnya adalah sebagai berikut:
Selanjutnya, pastikan startup aplikasi Anda (Startup.cs) dikonfigurasi untuk menggunakan MVC dengan benar dan menghadirkan baris berikut (tambahkan jika tidak):
.. dan akhirnya memodifikasi komponen Anda untuk ditautkan ke controller, misalnya (contoh berbasis iteratif menggunakan kelas kustom):
Semoga ini membantu siapa saja yang berjuang (seperti saya!) Untuk mendapatkan jawaban yang tepat untuk pertanyaan yang tampaknya sederhana ini di ranah Blazor ...!
sumber