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:
// ...
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.
// 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.
// ...
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 on “Response.TransmitFile, nueva forma para enviar archivos al cliente en ASP.NET 2”
lo mismo, pero en VB??????
Hola, Tan solo quiero dar las gracias al autor del articulo.!!
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
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
"
Hola muchas gracias, me ha servido mucho este articulo...
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!
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
Muy bueno, ¡Muchas gracias!