2012-06-20 42 views
66

Tôi đang sử dụng ASP.NET Web API.
Tôi muốn tải xuống tệp PDF có C# từ API (API tạo).Microsoft Web Api trả về một tệp? sử dụng byte []?

Tôi chỉ có thể trả lại mã số byte[]? và cho ứng dụng C# Tôi có thể chỉ cần làm:

byte[] pdf = client.DownloadData("urlToAPI");? 

File.WriteAllBytes()? 
+0

"API Web"? Chính xác ý của bạn là gì? Vui lòng đọc http://tinyurl.com/so-hints và chỉnh sửa câu hỏi của bạn. –

+1

@JonSkeet: API Web là một tính năng mới trong phiên bản mới nhất của ASP.NET. Xem http://www.asp.net/whitepapers/mvc4-release-notes#_Toc317096197 –

+1

@Robert: Cảm ơn - thẻ làm cho nó rõ ràng hơn, mặc dù đề cập đến "ASP.NET Web API" sẽ vẫn rõ ràng hơn. Lỗi của một phần MS đối với tên chung chung của rác quá :) –

Trả lời

115

Tốt hơn để trở HttpResponseMessage với StreamContent bên trong của nó.

Dưới đây là ví dụ:

public HttpResponseMessage GetFile(string id) 
{ 
    if (String.IsNullOrEmpty(id)) 
     return Request.CreateResponse(HttpStatusCode.BadRequest); 

    string fileName; 
    string localFilePath; 
    int fileSize; 

    localFilePath = getFileFromID(id, out fileName, out fileSize); 

    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); 
    response.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read)); 
    response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
    response.Content.Headers.ContentDisposition.FileName = fileName; 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); 

    return response; 
} 

UPD từ bình luận bằng patridge: bất cứ ai khác nên đến đây tìm cách để gửi ra một phản ứng từ một mảng byte thay vì một tập tin thực tế, bạn sẽ muốn sử dụng ByteArrayContent mới (someData) thay vì StreamContent (xem here).

+1

Điều đầu tiên - mã này sẽ gây ra một ngoại lệ vì bạn đang khởi tạo hai đối tượng FileStream chỉ vào cùng một tệp. Điều thứ hai là bạn không muốn sử dụng câu lệnh "Using", bởi vì ngay sau khi biến nằm ngoài phạm vi, .NET sẽ loại bỏ nó và bạn sẽ nhận được thông báo lỗi về kết nối cơ bản đang bị đóng. –

+1

@BrandonMontgomery Ok, bạn có quyền. Cảm ơn! – Regfor

+38

Nếu có ai khác ở đây tìm cách gửi phản hồi từ mảng byte thay vì tệp thực, bạn sẽ muốn sử dụng 'ByteArrayContent mới (someData) 'thay vì' StreamContent' (xem [ở đây] (http: //stackoverflow.com/a/12468615/48700)). – patridge

22

tôi đã thực hiện các hành động sau:

[HttpGet] 
[Route("api/DownloadPdfFile/{id}")] 
public HttpResponseMessage DownloadPdfFile(long id) 
{ 
    HttpResponseMessage result = null; 
    try 
    { 
     SQL.File file = db.Files.Where(b => b.ID == id).SingleOrDefault(); 

     if (file == null) 
     { 
      result = Request.CreateResponse(HttpStatusCode.Gone); 
     } 
     else 
     { 
      // sendo file to client 
      byte[] bytes = Convert.FromBase64String(file.pdfBase64); 


      result = Request.CreateResponse(HttpStatusCode.OK); 
      result.Content = new ByteArrayContent(bytes); 
      result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
      result.Content.Headers.ContentDisposition.FileName = file.name + ".pdf"; 
     } 

     return result; 
    } 
    catch (Exception ex) 
    { 
     return Request.CreateResponse(HttpStatusCode.Gone); 
    } 
} 
+0

Điều này thực sự trả lời câu hỏi – Mick

0

Ví dụ với IHttpActionResult trong ApiController.

[HttpGet] 
[Route("file/{id}/")] 
public IHttpActionResult GetFileForCustomer(int id) 
{ 
    if (id == 0) 
     return BadRequest(); 

    var file = GetFile(id); 

    IHttpActionResult response; 
    HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.OK); 
    responseMsg.Content = new ByteArrayContent(file.SomeData); 
    responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
    responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName; 
    responseMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); 
    response = ResponseMessage(responseMsg); 
    return response; 
} 

Nếu bạn không muốn tải về PDF và sử dụng một trình duyệt được xây dựng trong người xem PDF thay vì loại bỏ hai dòng sau:

responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName; 
+0

Bước tiếp theo là gì? Nó sẽ làm việc với chỉ này? –

+0

@ElbertJohnFelipe Có, bạn lấy tập tin với 'var file = GetFile (id);'. 'file.SomeData' là một Byte Array (' byte [] ') và' file.FileName'is 'string'. – Ogglas

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