Apa perbedaan antara empat Hasil File di ASP.NET MVC

137

ASP.NET memiliki empat jenis hasil file:

  • FileContentResult: Mengirim konten file biner ke respons.
  • FilePathResult: Mengirim konten file ke respons
  • FileResult: Mengembalikan keluaran biner untuk ditulis ke respons
  • FileStreamResult: Mengirim konten biner ke respons dengan menggunakan contoh Stream

Deskripsi tersebut diambil dari MSDN dan dengan pengecualian FileStreamResult, tiga suara pertama identik. Lalu apa perbedaan diantara keduanya?

Robert MacLean
sumber

Jawaban:

179

FileResult adalah kelas dasar abstrak untuk yang lainnya.

  • FileContentResult - Anda menggunakannya ketika Anda memiliki array byte yang ingin Anda kembalikan sebagai file
  • FilePathResult - ketika Anda memiliki file di disk dan ingin mengembalikan isinya (Anda memberikan jalur)
  • FileStreamResult - Anda memiliki aliran terbuka, Anda ingin mengembalikan isinya sebagai file

Namun, Anda jarang harus menggunakan kelas-kelas ini - Anda bisa menggunakan salah satu Controller.Filekelebihan beban dan biarkan ASP.NET MVC melakukan keajaiban untuk Anda.

maciejkow.dll
sumber
29

Pertanyaan bagus ... dan perlu detail lebih lanjut. Saya menemukan diri saya di sini sebagai akibat dari situasi yang menarik. Kami mengirimkan beberapa lampiran pdf melalui lingkungan MVC3 / C #. Kode kami dirilis dan kami mulai mendapatkan beberapa tanggapan dari klien kami bahwa unduhan berperilaku aneh saat mereka menggunakan Chrome dan jenis file diubah menjadi 'pdf-, attachment.pdf-, attachment'. Yup ... Anda mengerti ... semuanya. Jadi, seseorang dapat menulis ulang menjadi 'pdf' dan file tersebut akan tetap tersimpan utuh, tapi sungguh berantakan!

Jadi, untuk menggambarkan situasi awal, kami menyetel header 'Content-Disposition' kemudian mengembalikan FileContentResult ...

var cd = new System.Net.Mime.ContentDisposition
            {
                FileName = result.Attachment.FileName,
                Inline = false
            };
            Response.AppendHeader("Content-Disposition", cd.ToString());

return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);

Tampak bagus. Bekerja dengan baik di IE. Jadi saya melakukan penelitian dan mencoba menerapkan FileStreamResult sebagai gantinya (menjaga penyetel Content-Disposition):

MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));

Ini memperbaiki masalah di Chrome! Hmmm ... tapi mengapa sih harus saya harus mengambil array byte saya yang sangat baik dan mengalirkannya dan kemudian mengembalikannya melalui ini untuk mendapatkan nama file berfungsi dengan benar?

Lalu datanglah Fiddler.

Dengan FileContentResult, saya mendapat 2 Content-Dispositions di header. Dengan FileStreamResult, saya mendapat 1.

FileContentResult menambahkan header Content-Disposition saat memberikan Nama File dan Chrome menganggap kelipatan header ini sebagai kesalahan.

Reaksi yang aneh ... tapi yang pasti bagus untuk diketahui.

beauXjames.dll
sumber
3
Sekadar tip, di .NET 4+ Anda dapat menggunakan System.Web.MimeMapping.GetMimeMapping(filename)untuk mengumpulkan jenis pantomim jika Anda tidak dapat mengaksesnya dengan mudah.
GONeale
4
Memberikan nama file ke Filehasil berarti menyetel FileDownloadNamepropertinya, yang menyetel Content-Dispositionheader untuk Anda. Dan itu benar mendukung nama file utf-8, yang tidak ContentDispositionmembantu kelas (lihat komentar saya di sini untuk lebih jelasnya).
Frédéric
1
Ya, terima kasih @ Frédéric, Anda sendiri dari semua posting SO telah menjelaskan kepada saya apa yang terjadi!
Nacht