Response.TransmitFile, nueva forma para enviar archivos al cliente en ASP.NET 2

Existen algunos escenarios donde hay la necesidad de que antes de autorizar la descarga de un archivo desde nuestra aplicación, debamos realizar algún tipo de proceso. En estos casos lo que básicamente hacía es lo siguiente:

csharp:
// Algun tipo de validación o proceso
// ...
string file = Request.Params["file"];
if (!string.IsNullOrEmpty(file))
{
    file = Path.Combine(Server.MapPath("downloads"), Path.GetFileName(file));

    Response.Clear();
    Response.ContentType = "application/octect-stream";
    Response.AddHeader("Content–Disposition", "attachment; filename=foo.xyz");
    Response.WriteFile(file);
    Response.End();
}

Si bien es cierto que el código mostrado funcionaba bien para archivos pequeños, el problema se presentaba cuando los archivos tenían un tamaño grande, puesto que este método carga el contenido del archivo en memoria antes de enviarlo al cliente. Para evitar este problema, tal como se puede observar en la página de soporte de Microsoft, bastaba enviar pequeñas porciones del archivo a la vez.

csharp:
System.IO.Stream iStream = null;

// Búfer para leer 10 KB en el fragmento: byte[] buffer = new Byte[10000];
// Longitud del archivo:
int length;

// Número total de bytes que leer:
long dataToRead;

// Identificar el archivo que descargar incluyendo su ruta de acceso.
string filepath = "DownloadFileName";

// Identificar el nombre de archivo.
string filename = System.IO.Path.GetFileName(filepath);

try
{ // Abrir el archivo.
    iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

    // Número total de bytes que leer: dataToRead = iStream.Length;
    Response.ContentType = "application/octet-stream"; Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);

    // Leer los bytes.
    while (dataToRead > 0)
    { // Comprobar que el cliente está conectado.
        if (Response.IsClientConnected)
        { // Read the data in buffer.
            length = iStream.Read(buffer, 0, 10000);

            // Escribir los datos en la secuencia de salida actual.
            Response.OutputStream.Write(buffer, 0, length);

            // Vaciar los datos en la salida HTML.
            Response.Flush();

            buffer = new Byte[10000]; dataToRead = dataToRead - length;
        }
        else
        { //impedir un bucle infinito si el usuario se desconecta dataToRead = -1;
        }
    }
}
catch (Exception ex)
{ // Capturar el error, si lo hay.
    Response.Write("Error : " + ex.Message);
}
finally
{
    if (iStream != null)
    { //Cerrar el archivo.
        iStream.Close();
    }
}

En ASP.NET 2, se incluye el nuevo método TransmitFile para la clase HttpResponse, que hace lo mismo que el método WriteFile pero sin las limitaciones ni problemas que tiene este último.

csharp:
// Algun tipo de validación o proceso
// ...
string file = Request.Params["file"];
if (!string.IsNullOrEmpty(file))
{
    file = Path.Combine(Server.MapPath("downloads"), Path.GetFileName(file));

    Response.Clear();
    Response.ContentType = "application/octect-stream";
    Response.AddHeader("Content–Disposition", "attachment; filename=foo.xyz");
    Response.TransmitFile(file);
    Response.End();
}

8 Replies to “Response.TransmitFile, nueva forma para enviar archivos al cliente en ASP.NET 2”

  1. Saludos, tengo un problema a la hora de descargar un archivo del servidor usando Response.TransmitFile(file) o Response.WriteFile(file), el problema es el siguiente el archivo si se descarga pero al final del archivo me incluye esto

    CPMDIOT-SAT

    ojala peuedan ayudarme y gracias de antemano

  2. Saludos, tengo un problema a la hora de descargar un archivo del servidor usando Response.TransmitFile(file) o Response.WriteFile(file), el problema es el siguiente el archivo si se descarga pero al final del archivo me incluye esto

    "

    CPMDIOT-SAT

    "

  3. hola tengo un problema y ojala puedan ayudarme.. loq ue pasa es q tengo un sistema q crea una carpeta comprimida, la cual tiene q devolverse al cliente. (guardar o abrir)... el problema es q cuando esa carpeta tiene mas de un archivo, me cambia el tamanio del comprimido, al descargar, es decir en el servidor mi archivo mide 100kb a la hora de descargar, mide 200kb y no me deja abrirlo en el clietne. me arrooja el error de es una carpeta no valida o es corrupta...

    por favor.. si me pudieran orientar!!

    gracias!

  4. hola muy buen articulo, esta bien quisira saber como hacerle a la hora de la descarga en lugar que salga el dialogo de guardar enuna ruta especifica, que automaticamente se guarde en una ruta que se de por default, saludos y muy buen articulo

Comments are closed.