2009-04-08 59 views
101

Trong WebForms, tôi sẽ thường có mã như thế này để cho trình duyệt trình bày một "Download File" cửa sổ bật lên với một kiểu tập tin tùy ý, giống như một PDF, và một tên tập tin:Tôi làm cách nào để trình bày tệp để tải xuống từ bộ điều khiển MVC?

Response.Clear() 
Response.ClearHeaders() 
''# Send the file to the output stream 
Response.Buffer = True 

Response.AddHeader("Content-Length", pdfData.Length.ToString()) 
Response.AddHeader("Content-Disposition", "attachment; filename= " & Server.HtmlEncode(filename)) 

''# Set the output stream to the correct content type (PDF). 
Response.ContentType = "application/pdf" 

''# Output the file 
Response.BinaryWrite(pdfData) 

''# Flushing the Response to display the serialized data 
''# to the client browser. 
Response.Flush() 
Response.End() 

Làm thế nào để thực hiện như nhau nhiệm vụ trong ASP.NET MVC?

Trả lời

163

Trả lại một FileResult hoặc FileStreamResult từ hành động của bạn, tùy thuộc vào việc tệp có tồn tại hay bạn tạo tệp khi đang di chuyển.

public ActionResult GetPdf(string filename) 
{ 
    return File(filename, "application/pdf", Server.UrlEncode(filename)); 
} 
+10

Đây là một ví dụ tuyệt vời về lý do tại sao ASP.NET MVC tuyệt vời. Những gì bạn đã làm trước đây trong 9 dòng mã tìm kiếm khó hiểu có thể được thực hiện trong một dòng. Dễ dàng hơn nhiều! –

+0

Cảm ơn tvanfosson, tôi đã tìm kiếm giải pháp tốt nhất để làm điều này, và điều này thật tuyệt. –

+0

Điều này đòi hỏi một phần mở rộng tập tin trên tên tập tin hoặc nếu không nó sẽ hoàn toàn bỏ qua tên tập tin và contenttype và chỉ cố gắng để dòng tập tin vào trình duyệt. Nó cũng sẽ chỉ sử dụng tên trang web nếu trình duyệt không nhận dạng được contenttype (tức là octet-stream) khi nó buộc tải xuống và nó sẽ không có phần mở rộng nào cả. – EdenMachine

4

Bạn nên xem phương pháp Tệp của Bộ điều khiển. Đây chính xác là những gì nó làm. Nó trả về một FilePathResult thay vì một ActionResult.

-3

loại tập tin Sử dụng ashx và sử dụng cùng mã

3

mgnoonan,

Bạn có thể làm điều này để trả lại một FileStream:

/// <summary> 
/// Creates a new Excel spreadsheet based on a template using the NPOI library. 
/// The template is changed in memory and a copy of it is sent to 
/// the user computer through a file stream. 
/// </summary> 
/// <returns>Excel report</returns> 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult NPOICreate() 
{ 
    try 
    { 
     // Opening the Excel template... 
     FileStream fs = 
      new FileStream(Server.MapPath(@"\Content\NPOITemplate.xls"), FileMode.Open, FileAccess.Read); 

     // Getting the complete workbook... 
     HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true); 

     // Getting the worksheet by its name... 
     HSSFSheet sheet = templateWorkbook.GetSheet("Sheet1"); 

     // Getting the row... 0 is the first row. 
     HSSFRow dataRow = sheet.GetRow(4); 

     // Setting the value 77 at row 5 column 1 
     dataRow.GetCell(0).SetCellValue(77); 

     // Forcing formula recalculation... 
     sheet.ForceFormulaRecalculation = true; 

     MemoryStream ms = new MemoryStream(); 

     // Writing the workbook content to the FileStream... 
     templateWorkbook.Write(ms); 

     TempData["Message"] = "Excel report created successfully!"; 

     // Sending the server processed data back to the user computer... 
     return File(ms.ToArray(), "application/vnd.ms-excel", "NPOINewFile.xls"); 
    } 
    catch(Exception ex) 
    { 
     TempData["Message"] = "Oops! Something went wrong."; 

     return RedirectToAction("NPOI"); 
    } 
} 
57

Buộc thực hiện tải của một PDF tệp thay vì bị plugin PDF của trình duyệt xử lý:

public ActionResult DownloadPDF() 
{ 
    return File("~/Content/MyFile.pdf", "application/pdf", "MyRenamedFile.pdf"); 
} 

Nếu bạn muốn để trình duyệt xử lý theo hành vi mặc định của nó (plugin hoặc tải xuống), chỉ cần gửi hai tham số.

public ActionResult DownloadPDF() 
{ 
    return File("~/Content/MyFile.pdf", "application/pdf"); 
} 

Bạn cần sử dụng thông số thứ ba để chỉ định tên cho tệp trên hộp thoại trình duyệt.

CẬP NHẬT: Charlino là đúng, khi chuyển tham số thứ ba (tên tệp tải xuống) Content-Disposition: attachment; được thêm vào Tiêu đề phản hồi của Http. Giải pháp của tôi là gửi application\force-download làm loại mime, nhưng điều này tạo ra sự cố với tên tệp của tệp tải xuống để thông số thứ ba được yêu cầu để gửi tên tệp tốt, do đó, không cần phải tải xuống tải xuống.

+6

Về mặt kỹ thuật, đó không phải là những gì đang xảy ra.Về mặt kỹ thuật khi bạn thêm tham số thứ ba, khung MVC sẽ thêm tiêu đề 'content-disposition: attachment; filename = MyRenamedFile.pdf' - đây là những gì buộc tải xuống. Tôi sẽ đề nghị bạn đặt kiểu MIME trở lại 'application/pdf'. – Charlino

+2

Cảm ơn Charlino, tôi đã không nhận ra thông số thứ ba đang làm điều đó, tôi nghĩ đó chỉ là thay đổi tên tập tin. – guzart

+2

+1 để cập nhật câu trả lời của bạn và giải thích tham số thứ ba + 'Nội dung-Bố trí: tệp đính kèm; – Charlino

6

Bạn có thể làm điều tương tự trong Razor hoặc trong điều khiển, như vậy ..

@{ 
    //do this on the top most of your View, immediately after `using` statement 
    Response.ContentType = "application/pdf"; 
    Response.AddHeader("Content-Disposition", "attachment; filename=receipt.pdf"); 
} 

Hoặc trong điều khiển ..

public ActionResult Receipt() { 
    Response.ContentType = "application/pdf"; 
    Response.AddHeader("Content-Disposition", "attachment; filename=receipt.pdf"); 

    return View(); 
} 

Tôi cố gắng này trong Chrome và IE9, cả hai là tải xuống tệp pdf.

Tôi có lẽ nên thêm Tôi đang sử dụng RazorPDF để tạo tệp PDF của mình. Đây là một blog về nó: http://nyveldt.com/blog/post/Introducing-RazorPDF

Các vấn đề liên quan