Chúng tôi có một số tệp được lưu trữ trong cơ sở dữ liệu sql. Trên một mẫu ASP.NET MVC3, chúng tôi hiển thị 2 liên kết:Làm cách nào để tránh tiêu đề trùng lặp nội dung trùng lặp với MVC3 FileContentResult?
Xem tập tin này | Tải xuống tệp này
Các liên kết này đi đến các phương pháp hành động tương ứng này. Quá trình tải xuống hoạt động như mong đợi - việc nhấp vào liên kết sẽ buộc hộp thoại lưu trong trình duyệt. Tuy nhiên, màn hình hiển thị sẽ khiến các tiêu đề trùng lặp Content-Disposition được gửi tới trình duyệt, dẫn đến lỗi trên Chrome và một trang trống trong Firefox.
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
Response.AddHeader("Content-Disposition",
string.Format("inline; filename={0}", file.Name));
return File(file.Content, file.MimeType, file.Name);
}
}
[ActionName("download-file")]
public virtual ActionResult DownloadFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
return File(file.Content, file.MimeType, file.Name);
}
}
Sau đây là 2 tiêu đề gửi đến trình duyệt cho hành động hiển thị:
Content-Disposition: inline; filename=name-of-my-file.pdf
Content-Disposition: attachment; filename="name-of-my-file.pdf"
Tôi đã cố gắng thay đổi tiêu đề nội dung bố trí tùy chỉnh của tôi để bọc các tên tập tin trong dấu ngoặc kép, nhưng nó vẫn gửi 2 tiêu đề cho trình duyệt. Tôi cũng đã cố gắng loại bỏ tiêu đề Content-Disposition trước khi thêm phần tùy chỉnh, nhưng nó xuất hiện phần đầu đính kèm đang được thêm sau khi FileContentResult được trả về.
Mã này được sử dụng để hoạt động. Tôi đã chạy thử nghiệm ngay hôm qua và nhận thấy nó không còn hoạt động trong Chrome hoặc Firefox nữa. Điều này có thể là do các bản cập nhật trong trình duyệt. IE8 và Safari vẫn mở tệp một cách chính xác.
Cập nhật
Cảm ơn một lần nữa Darin, bạn là chính xác. Chúng tôi thực sự đã sử dụng phương pháp này vì another question you answered.
Một chút thông tin thêm về cách này sau cùng đã được giải quyết trên cuối của chúng tôi, chúng tôi có một lộ trình tùy chỉnh cho các liên kết tập tin hiển thị:
context.MapRoute(null,
"path/to/display-file-attachment/{fileId}/{fileName}",
new
{
area = "AreaName",
controller = "ControllerName",
action = "DisplayFile",
}
);
Các siêu liên kết trên trang trôi qua tên tập tin với phương pháp hành động thông qua thông số tuyến đường, do đó, nó đã là một phần của URL. Do đó, chúng tôi không cần phải thêm tiêu đề tùy chỉnh bố cục nội dung để làm cho tên tệp phù hợp với hệ thống khi người dùng quyết định tải xuống (bằng cách nhấp vào biểu tượng lưu trong trình xem PDF của trình duyệt). Vì vậy, chúng tôi chỉ sử dụng này:
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
// no custom content-disposition header, and no 3rd fileName argument
return File(file.Content, file.MimeType);
}
}
Firefox và Chrome đã thực sự trở thành khắt khe hơn trong việc xử lý của họ về header Content-Disposition. –
@JulianReschke, bạn vui lòng xây dựng trên các ký tự không phải ASCII? Chúng tôi chưa thử nghiệm tính năng này với các ký tự unicode trong tên tệp. – danludwig
đối với không phải ASCII trong tên tệp trong C-D để "hoạt động" trong tất cả các trình duyệt, máy chủ hiện cần phải thực hiện Tác nhân người dùng đánh hơi. Xem http://greenbytes.de/tech/tc2231/ và http://greenbytes.de/tech/webdav/rfc6266.html. Tôi có nghi ngờ rằng ASP.net có quyền này, nhưng tôi rất muốn tìm ra cách khác. –