2011-05-06 34 views
5

Estoy usando un controlador (.ashx) para servir algunos archivos. Tengo una carpeta donde almaceno ebooks. Les nombrar por el PK libros, y cada libro puede tener unos formatos diferentes:¿Cómo puedo enviar al cliente varios archivos para descargar

211.html 
211.pdf 
211.prc 

El siguiente código de prueba de descarga con éxito un libro.

context.Response.ContentType = "application/octet-stream"; 
context.Response.AppendHeader("Content-Disposition", "attachment;filename=myfile.pdf"); 
context.Response.TransmitFile(context.Server.MapPath("~/Media/eBooks/212.pdf")); 

¿Cómo puedo servir al cliente los tres formatos diferentes? (La organización de clientes existente no está en una carpeta)

yo estaba tratando de hacer algo como esto:

DirectoryInfo bookDir = new DirectoryInfo(context.Server.MapPath("~/Media/eBooks")); 
FileInfo[] f = bookDir.GetFiles(); 

foreach (var n in f) 
{ 
    context.Response.AppendHeader("Content-Disposition", "attachment;filename=myfile.pdf"); 
    context.Response.TransmitFile(context.Server.MapPath("~/Media/eBooks/212.pdf")); 
} 

Pero se descarga un archivo con ninguna extensión de archivo.

Respuesta

8

La única forma en que puede enviar varios archivos en una sola respuesta es colocarlos dentro de un paquete de archivo, p. un archivo .zip. Eso es al menos algo que se puede hacer con el código, usando varias herramientas (IIRC ahora hay un empaquetador zip dentro del framework .NET principal; de lo contrario, SharpZipLib hará el trabajo bien).

1

Para enviar múltiples archivos a descargar, debe comprimirlos usando sharpziplib u otra utilidad de compresión de archivos, los archivos deben estar comprimidos y luego el enlace de descarga puede enviarse al cliente para descargarlos de una vez. el siguiente código usa la biblioteca ICSharpCode.SharpZipLib.dll. Puede llamar a esta clase y pasar sus archivos que desea comprimir.

public string Makezipfile(string[] files) 
    { 

    string[] filenames = new string[files.Length]; 


     for (int i = 0; i < files.Length; i++) 
      filenames[i] = HttpContext.Current.Request.PhysicalApplicationPath + files[i].Replace(HttpContext.Current.Request.UrlReferrer.ToString(), ""); 
    string DirectoryName = filenames[0].Remove(filenames[0].LastIndexOf('/')); 
    DirectoryName = DirectoryName.Substring(DirectoryName.LastIndexOf('/') + 1).Replace("\\", ""); 

    try 
    { 

     string newFile = HttpContext.Current.Request.PhysicalApplicationPath + "your image directory\\" + DirectoryName + ".zip"; 
     if (File.Exists(newFile)) 
      File.Delete(newFile); 

     using (ZipFile zip = new ZipFile()) 
     { 

      foreach (string file in filenames) 
      { 

       string newfileName = file.Replace("\\'", "'"); 
       zip.CompressionLevel = 0; 
       zip.AddFile(newfileName, ""); 
      } 

      zip.Save(newFile); 
     } 
    } 
    catch (Exception ex) 
    { 
     //Console.WriteLine("Exception during processing {0}", ex); 
     Response.Write(ex); 
     // No need to rethrow the exception as for our purposes its handled. 
    } 
    string a; 
    a = "your images/" + DirectoryName + ".zip"; 
    return a; 

} 
1

Reconozco las buenas soluciones Zip mencionados aquí, pero, alternativamente, podría hacer 3 llamadas al controlador usando javascript/XHR, solicitando un formato de archivo diferente cada vez?

Es cierto que está restringido por el número de solicitudes simultáneas admitidas por el navegador, aunque creo que el navegador pondrá las solicitudes en cola por encima del límite.

El beneficio es que el usuario no necesitará tratar con un archivo zip, lo que puede confundirlos. En su lugar, deberían obtener 3 descargas separadas.

+0

estoy de acuerdo, pero lo que creo que si puede hacer una identificación de proceso para cada descarga de archivo zip, entonces puede hacer un seguimiento de cada descarga y el proceso se ejecutará en segundo plano. Si un usuario inicia un archivo comprimido para descargar, el usuario puede enviar un id. De proceso y un archivo para descargar, al mismo tiempo si inicia otro archivo comprimido para descargar, de modo que se generará un segundo ID de proceso y se enviará a la clase de fondo. cuando el proceso finalizó en segundo plano, devuelve la ruta del id del proceso y los archivos zip para descargar. – safi

Cuestiones relacionadas