2010-08-30 16 views
5

Quiero permitir la descarga de archivos en mi aplicación MVC, sin simplemente usar un hipervínculo. Planeo usar una imagen o similar y hacer que se pueda hacer clic usando jQuery. Por el momento tengo un simple solo para probar.Descarga de archivos en Asp.Net MVC 2

Encontré una explicación de cómo realizar la descarga a través de un método de acción, pero desafortunadamente el ejemplo todavía tenía enlaces de acción.

Ahora, puedo llamar al método de acción de descarga muy bien, pero no pasa nada. Supongo que tengo que hacer algo con el valor de retorno, pero no sé qué ni cómo.

Aquí está el método de acción:

public ActionResult Download(string fileName) 
    { 
     string fullName = Path.Combine(GetBaseDir(), fileName); 
     if (!System.IO.File.Exists(fullName)) 
     { 
      throw new ArgumentException("Invalid file name or file does not exist!"); 
     } 

     return new BinaryContentResult 
     { 
      FileName = fileName, 
      ContentType = "application/octet-stream", 
      Content = System.IO.File.ReadAllBytes(fullName) 
     }; 
    } 

Aquí está la clase BinaryContentResult:

public class BinaryContentResult : ActionResult 
{ 
    public BinaryContentResult() 
    { } 

    public string ContentType { get; set; } 
    public string FileName { get; set; } 
    public byte[] Content { get; set; } 

    public override void ExecuteResult(ControllerContext context) 
    { 

     context.HttpContext.Response.ClearContent(); 
     context.HttpContext.Response.ContentType = ContentType; 

     context.HttpContext.Response.AddHeader("content-disposition", 

               "attachment; filename=" + FileName); 

     context.HttpContext.Response.BinaryWrite(Content); 
     context.HttpContext.Response.End(); 
    } 
} 

que llamo el método de acción a través de:

<span id="downloadLink">Download</span> 

que se hace se puede hacer clic a través de:

$("#downloadLink").click(function() { 
    file = $(".jstree-clicked").attr("rel") + "\\" + $('.selectedRow .file').html(); 
    alert(file); 
    $.get('/Customers/Download/', { fileName: file }, function (data) { 
     //Do I need to do something here? Or where? 
    }); 
}); 

Tenga en cuenta que el parámetro de nombre de archivo se recibe correctamente por el método de acción y todo, es solo que no pasa nada, así que supongo que necesito manejar el valor de retorno de alguna manera?

+0

Tu clase 'BinaryContentResult' no debería existir. Use 'FileResult'. – SLaks

+0

Ok, ¿eso es una clase estándar o algo así? ¿Cómo me ayudaría a resolver el problema? – Anders

Respuesta

4

No desea descargar el archivo con AJAX, desea que el navegador lo descargue. $ .get() lo buscará pero no hay forma de guardar localmente desde Javascript, por razones de seguridad el navegador debe estar involucrado. Simplemente redirija a la ubicación de descarga y el navegador lo manejará por usted.

+0

Bien, ¿podría especificar qué quiere decir que debería hacer, por favor? Lo que quiero decir es que podría usar enlaces simples para hacer esto, como en el ejemplo del que obtuve esto, y la página no se volverá a cargar, sino simplemente abrir un diálogo de guardar como. Quiero el mismo comportamiento, pero haciendo clic en el lapso en su lugar (que determina qué archivo se va a descargar por una clase de selección). ¿Podrías especificar con algún código? ¡Gracias! – Anders

+1

Use 'document.location.href = ...' para indicarle al navegador que vaya a la url para descargar el archivo. Verá el encabezado de disposición de contenido y lo mostrará como una descarga, no como una página. –

+0

¡Perfecto! Solo una pregunta más antes de cerrar este tema: cuando aparece el cuadro de diálogo Guardar como, el nombre del archivo se concatena con guiones bajos de la ruta de acceso y el nombre del archivo, como por ejemplo: folder_folder_file.txt. ¿Cómo? Quiero decir, la descarga funciona y todo, pero quiero que tenga su nombre de archivo original. (Pasando por el método de acción y BinaryContentResult, la variable FileName tiene una ruta regular: carpeta \\ carpeta \\ archivo.txt. No puedo entender dónde tiene lugar esta concatenación con guiones bajos. ¿Alguna idea? – Anders

Cuestiones relacionadas