2010-02-10 15 views
10

Quiero enviar un archivo al navegador desde un sitio web utilizando un servicio web. Actualmente estoy leyendo el archivo en una matriz de bytes base64 y devolvéndolo desde el servicio web. Se llama a este servicio web desde un sitio web, y estoy atascado en cómo insertarlo como el archivo original en el navegador. Idealmente, me gustaría leer la matriz de bytes en una secuencia de memoria, y luego simplemente escribirla en la secuencia de respuesta si es posible para que el usuario final simplemente descargue el archivo.Descargar archivo del servicio web - en el sitio ASP.NET

+0

Y lo es el problema que estás teniendo con ese enfoque? No hizo una pregunta, por lo que probablemente se cerrará rápidamente. – Oded

Respuesta

12

Primero, en lugar de enviar una matriz de bytes base64, haga que su servicio web simplemente devuelva una matriz de bytes para su archivo. Response.OutputStream.Write() automáticamente codificará automáticamente sus bytes en base64, por lo que también podría tenerlos sin codificar en su flujo de memoria.

En segundo lugar, necesitará algo más que los bytes. Necesitará metadatos asociados con el archivo. Para el siguiente fragmento, he colocado todos los metadatos en una clase separada (instancia local llamada "archivo"). A continuación, sólo tiene que utilizar este fragmento, una vez que tenga los datos que necesita:

Response.Clear(); 
Response.ClearHeaders(); 
Response.ContentType = file.ContentType; 
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.FileName + "\""); 
Response.AddHeader("Content-Length", file.FileSize.ToString()); 
Response.OutputStream.Write(file.Bytes, 0, file.Bytes.Length); 
Response.Flush(); 
Response.End(); 
+3

Cuidado con Response.End() http://stackoverflow.com/questions/1087777/is-response-end-considered-harmful –

+0

@Todd Smith: Gracias por el puntero. Estaba al tanto del problema, pero tiene razón en que otros no; podría ser un problema serio. En el caso de una descarga de archivos, sin embargo, no hay ningún procesamiento adicional que desee o deba hacer, y por lo tanto 'Response.End()' * es * probable que sea la llamada correcta. Ciertamente es en mi caso. – Randolpho

+2

¿Debo usar Response.Close() en lugar de Repsonse.End()? – user210757

3

Es posible, tendrá que asegurarse de que establece explícitamente la ContentType del HttpResponse, por ejemplo:

Response.ContentType = "image/jpeg"; 
Response.OutputStream.Write(buffer, 0, buffer.Length); 

Si desea controlar el nombre del archivo, se le tiene que añadir un contenido -Disposición encabezado. Google puede ayudarlo a encontrar la forma correcta de resolverlo.

+0

+1, aunque omitió Content-Disposition, que es lo más importante para las descargas de archivos. Editar: Y luego lo agregaste. Entonces ignora esto. :) – Randolpho

0

que realmente depende de la interfaz a su servicio web. Es decir, SOAP, REST, ASPX.

Una cosa que puedes intentar es cambiar el tipo de contenido en tu respuesta a "Application/octet-stream". O algo similar para decirle al receptor el tipo MIME.

Si usa el repositorio de WCF, puede usar Stream como un tipo de devolución en el servicio web.

1

Generalmente es una mala idea incrustar un archivo en un servicio web. Simplemente agrega sobrecarga y complejidad sin ningún beneficio real.

En su lugar, debe proporcionar un IHttpHandler para manejar la carga del archivo. La mayoría de los servidores web también proporcionan API auxiliares para simplificar esto, p. en ASP.NET se puede acceder al archivo cargado con:

HttpContext.Request.Files [0]

Hay un montón de secuencias de comandos de subida de archivos javascript que simplifican esta en el cliente: http://www.phpletter.com/Demo/AjaxFileUpload-Demo/

+0

en realidad estoy tratando de descargar archivos al cliente, no subirlos al servidor – user210757

+0

ese enlace es spam o perdió su contexto a tiempo. – mcy

Cuestiones relacionadas