Sự khác biệt giữa bốn kết quả tệp trong ASP.NET MVC


136

ASP.NET có bốn loại kết quả tệp khác nhau:

  • FileContentResult: Gửi nội dung của tệp nhị phân đến phản hồi.
  • FilePathResult: Gửi nội dung của tệp tới phản hồi
  • FileResult: Trả về đầu ra nhị phân để ghi vào phản hồi
  • FileStreamResult: Gửi nội dung nhị phân đến phản hồi bằng cách sử dụng một thể hiện Stream

Những mô tả đó được lấy từ MSDN và ngoại trừ FileStreamResult ba âm thanh đầu tiên giống hệt nhau. Vậy sự khác biệt giữa chúng là gì?

Câu trả lời:


176

FileResult là một lớp cơ sở trừu tượng cho tất cả những người khác.

  • FileContentResult - bạn sử dụng nó khi bạn có một mảng byte mà bạn muốn trả về dưới dạng tệp
  • FilePathResult - khi bạn có một tệp trên đĩa và muốn trả về nội dung của nó (bạn đưa ra một đường dẫn)
  • FileStreamResult - bạn có một luồng mở, bạn muốn trả về nội dung của nó dưới dạng tệp

Tuy nhiên, bạn sẽ hiếm khi phải sử dụng các lớp này - bạn chỉ có thể sử dụng một trong những Controller.Filetình trạng quá tải và để ASP.NET MVC làm điều kỳ diệu cho bạn.


29

Câu hỏi tuyệt vời ... và xứng đáng được biết thêm chi tiết. Tôi thấy mình ở đây là kết quả của một tình huống thú vị. Chúng tôi đã cung cấp một số tệp đính kèm pdf thông qua môi trường MVC3 / C #. Mã của chúng tôi đã được phát hành và chúng tôi bắt đầu nhận được một số phản hồi từ khách hàng của mình rằng các bản tải xuống hoạt động kỳ lạ khi họ đang sử dụng Chrome và loại tệp đang được chuyển đổi thành 'pdf-, tệp đính kèm.pdf-, tệp đính kèm'. Yup ... bạn hiểu rồi ... toàn bộ. Vì vậy, người ta có thể viết lại thành 'pdf' và tệp vẫn sẽ lưu nguyên vẹn, nhưng thật là một mớ hỗn độn!

Vì vậy, để mô tả tình huống ban đầu, chúng tôi đã đặt tiêu đề 'Xử lý nội dung' sau đó trả lại 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);

Có vẻ tốt. Hoạt động tốt trong IE. Vì vậy, tôi đã thực hiện một số nghiên cứu và thử triển khai FileStreamResult thay vào đó (giữ bộ cài đặt Xử lý nội dung):

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));

Nó đã khắc phục sự cố trong Chrome! Hmmm ... nhưng tại sao tôi phải lấy mảng byte hoàn toàn tốt của mình và truyền phát nó và sau đó trả lại qua đây để tên tệp hoạt động đúng không?

Sau đó đến Fiddler.

Với FileContentResult, tôi đã nhận được 2 Bố cục nội dung trong tiêu đề. Với FileStreamResult, tôi đã nhận được 1.

FileContentResult nối thêm tiêu đề Xử lý nội dung khi cung cấp Tên tệp và Chrome coi bội số của tiêu đề này là một lỗi.

Phản ứng kỳ lạ ... nhưng chắc chắn là một điều tốt để biết.


3
Chỉ cần một mẹo, trong .NET 4+, bạn có thể sử dụng System.Web.MimeMapping.GetMimeMapping(filename)để thu thập loại mime nếu bạn không thể truy cập dễ dàng.
GONeale

4
Cung cấp tên tệp cho Filekết quả có nghĩa là đặt thuộc tính của tệp FileDownloadName, đặt Content-Dispositiontiêu đề cho bạn. Và nó hỗ trợ chính xác tên tệp utf-8, không ContentDispositionhỗ trợ lớp (xem bình luận của tôi ở đây để biết thêm chi tiết).
Frédéric

1
Vâng, cảm ơn bạn @ Frédéric, bạn một mình trong số tất cả các bài viết SO đã giải thích cho tôi những gì đang xảy ra!
thuyền
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.