2012-06-20 18 views
66

Estoy usando ASP.NET Web API.
Quiero descargar un PDF con C# de la API (que genera la API).Microsoft Web Api devuelve un archivo? usar byte []?

¿Puedo hacer que la API devuelva un byte[]? y para la aplicación de C# ¿puedo hacer:

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

y

File.WriteAllBytes()? 
+0

"la Web API"? Qué quieres decir exactamente? Por favor, lea http://tinyurl.com/so-hints y edite su pregunta. –

+1

@JonSkeet: Web API es una nueva característica en la última versión de ASP.NET. Ver http://www.asp.net/whitepapers/mvc4-release-notes#_Toc317096197 –

+1

@Robert: Gracias - la etiqueta lo hace más claro, aunque referirse a "ASP.NET Web API" hubiera sido más claro aún. En parte, la culpa de MS también es un nombre genérico: –

Respuesta

115

mejor volver HttpResponseMessage con StreamContent dentro de ella.

Aquí es ejemplo:

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 del comentario de patridge: En caso de cualquier otra persona llegar hasta aquí en busca de enviar una respuesta por parte de una matriz de bytes en lugar de un archivo real, vas a desea utilizar el nuevo ByteArrayContent (someData) en lugar de StreamContent (consulte here).

+1

Lo primero es que este código causará una excepción ya que está actualizando dos objetos de FileStream apuntando al mismo archivo. Lo segundo es que no desea utilizar una instrucción "Using", porque tan pronto como la variable se salga del alcance, .NET lo eliminará y obtendrá mensajes de error sobre la conexión subyacente que se cierra. –

+1

@BrandonMontgomery Ok, tienes razón. ¡Gracias! – Regfor

+38

Si alguien más llega aquí buscando enviar una respuesta de una matriz de bytes en lugar de un archivo real, querrá usar 'new ByteArrayContent (someData)' en lugar de 'StreamContent' (ver [aquí] (http: //stackoverflow.com/a/12468615/48700)). – patridge

22

I hizo que la acción sigue:

[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

Esto realmente responde a la pregunta – Mick

0

Ejemplo con IHttpActionResult en 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; 
} 

Si no desea descargar el PDF y utilizar un navegadores construido en el visor de PDF en lugar retire las dos líneas siguientes:

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

¿Cuál es el siguiente paso? ¿Funcionará con solo esto? –

+0

@ElbertJohnFelipe Sí, obtienes el archivo con 'var file = GetFile (id);'. 'file.SomeData' es una matriz de bytes (' byte [] ') y' file.FileName'is 'string'. – Ogglas

Cuestiones relacionadas