Tôi đang gặp vấn đề khi gửi các tệp được lưu trữ trong cơ sở dữ liệu lại cho người dùng trong ASP.NET MVC. Những gì tôi muốn là một khung nhìn liệt kê hai liên kết, một để xem tệp và để cho mimetype được gửi tới trình duyệt xác định cách xử lý và liên kết kia để buộc tải xuống.
Nếu tôi chọn xem một tệp được gọi SomeRandomFile.bak
và trình duyệt không có chương trình liên quan để mở các tệp thuộc loại này, thì tôi không gặp vấn đề gì với việc mặc định nó là hành vi tải xuống. Tuy nhiên, nếu tôi chọn xem một tệp được gọi SomeRandomFile.pdf
hoặc SomeRandomFile.jpg
tôi muốn tệp chỉ đơn giản là mở. Nhưng tôi cũng muốn giữ một liên kết tải xuống sang một bên để tôi có thể buộc một dấu nhắc tải xuống bất kể loại tệp. Điều này có nghĩa không?
Tôi đã thử FileStreamResult
và nó hoạt động với hầu hết các tệp, hàm tạo của nó không chấp nhận tên tệp theo mặc định, vì vậy các tệp không xác định được gán tên tệp dựa trên URL (không biết tiện ích mở rộng để cung cấp dựa trên loại nội dung). Nếu tôi buộc tên tệp bằng cách chỉ định nó, tôi sẽ mất khả năng trình duyệt mở tệp trực tiếp và tôi nhận được lời nhắc tải xuống. Đã có người khác gặp phải điều này?
Đây là những ví dụ về những gì tôi đã thử cho đến nay.
//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};
Bất kỳ đề xuất?
CẬP NHẬT:
Câu hỏi này dường như tấn công hợp âm với rất nhiều người, vì vậy tôi nghĩ rằng tôi sẽ đăng một bản cập nhật. Cảnh báo về câu trả lời được chấp nhận dưới đây được Oskar thêm vào liên quan đến các ký tự quốc tế là hoàn toàn hợp lệ và tôi đã nhấn nó vài lần do sử dụng ContentDisposition
lớp. Kể từ khi tôi cập nhật triển khai để sửa lỗi này. Mặc dù đoạn mã dưới đây là từ sự xuất hiện gần đây nhất của tôi về vấn đề này trong ứng dụng ASP.NET Core (Full Framework), nó sẽ hoạt động với những thay đổi tối thiểu trong một ứng dụng MVC cũ hơn vì tôi đang sử dụng System.Net.Http.Headers.ContentDispositionHeaderValue
lớp.
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
}