viernes, 7 de agosto de 2009

ASP.NET - Descargar archivos del servicio web

ftws Una pregunta bastante frecuente:

Cómo descargo un archivo que está siendo administrado por un servicio web?

por ejemplo, descargarse archivos pdf… que podrían estar inclusive en otro servidor… osea, el servicio web es el intermediario, no tengo acceso a los archivos más que mediante el acceso al servicio web.

Vamos a ver, en realidad esto es muy sencillo.

Necesitamos dos cosas:

+ El servicio web y

+ La aplicación web que hace la petición de archivos.

1.- El servicio web

Imports System.Web.Services
Imports System.IO

<WebService(Namespace:="http://tempuri.org/")> _
Public Class Service1
    Inherits System.Web.Services.WebService

    <WebMethod()> _
    Public Function ReturnBytesToClient(ByVal FileName As String) As Byte()
        Dim fs As FileStream = Nothing

        Try
            Dim FilePath As String = Server.MapPath("~") & "\Files\" & FileName

            'obtenemos el archivo del servidor
            fs = File.Open(FilePath, FileMode.Open, FileAccess.Read)

            Dim byteBuffer(CInt(fs.Length - 1)) As Byte
            fs.Read(byteBuffer, 0, CInt(fs.Length))


            Return byteBuffer

        Catch exp As Exception
            Return Nothing
        Finally
            If Not fs Is Nothing Then fs.Close()
        End Try

    End Function

End Class

Ese es todo el código para el servicio web… lo explico:

Hay un método llamado ReturnBytesToClient el cual acepta un parámetro, ese parámetro es el nombre del archivo que se está solicitando… entonces… como ven en la imagen de arriba… dentro de la estructura de archivos del servicio web, hay una carpeta llamada Files, allí se guardan los archivos a despachar.

Cuando este método es invocado, accede al archivo mediante un filestream y luego eso se devuelve al cliente que lo solicita, como un conjunto de bytes.

2.- Aplicación web

Antes de utilizar el servicio web, tenemos que crear una referencia en nuestra aplicación web a dicho servicio web:

ftwapp

Este link muestra cómo añadir referencias a servicios web.

La referencia al servicio web debe tener un nombre, yo lo he llamado FileTransfers, como pueden ver en la imagen.

Luego, viene el código que recupera el archivo:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load

    RecuperarArchivoDelWebService()

End Sub

Private Sub RecuperarArchivoDelWebService()
    Dim NombreDelArchivoASolicitar As String = "SoftwareTest.pdf"

    Dim ws As New FileTranfers.Service1
    Dim bytes() As Byte = ws.ReturnBytesToClient(NombreDelArchivoASolicitar)

    Using ms As New IO.MemoryStream(bytes)
        ms.WriteTo(Response.OutputStream)
    End Using

End Sub

Esta es la versión más simple del método para recuperar el archivo… lo que hace este diminuto pero espectacular trozo de código es mostrar la ventanita de Guardar archivo. Ejecuten el código para ver el resultado.

Con eso ya hemos recuperado el archivo del servicio web.

Aquí les muestro una nueva versión del mismo método, el cual adicionalmente nos permite especificar cuál será el nuevo nombre del archivo:

Private Sub RecuperarArchivoDelWebService()
    Dim NombreDelArchivoASolicitar As String = "SoftwareTest.pdf"
    Dim NuevoNombreDelArchivo As String = "SoftwareTesting.pdf"

    Dim ws As New FileTranfers.Service1
    Dim bytes() As Byte = ws.ReturnBytesToClient(NombreDelArchivoASolicitar)

    Using ms As New IO.MemoryStream(bytes)
        Response.AddHeader("Content-Disposition", "attachment; filename=" & NuevoNombreDelArchivo)
        ms.WriteTo(Response.OutputStream)
    End Using

End Sub

;)

3 comentarios:

Unknown dijo...

Gracias Muy Bueno!!

Sergio dijo...

Si pero el código deja de ejecutarse...
Tengo

lblInforme.Text = "hola" y después la descarga:
...
Response.AddHeader("Content-Disposition"

y lblInforme.Text no vale "hola"

Segundo Serrano dijo...

Hola Sergio,

disculp, no entiendo bien lo que preguntas...
podrías explicarlo mejor?

Saludos