Response.TransmitFile, nueva forma para enviar archivos al cliente en ASP.NET 2
Por: alex | 20 Febrero 2007 | Ver comentarios |
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:
// 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.
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.
// 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();
}


blackhelmet
9 de Diciembre de 2007, 12:23:14 pm
lo mismo, pero en VB??????
Jonathan Gutierrez
16 de Enero de 2008, 05:08:10 pm
Hola, Tan solo quiero dar las gracias al autor del articulo.!!
JORGE
28 de Febrero de 2008, 12:23:01 pm
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
JORGE
28 de Febrero de 2008, 12:23:48 pm
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
“
Luli
17 de Julio de 2008, 10:58:04 am
Hola muchas gracias, me ha servido mucho este articulo…