2010-08-30 16 views
5

Desidero abilitare il download del file nella mia applicazione MVC, senza utilizzare semplicemente un collegamento ipertestuale. Ho in programma di usare un'immagine o qualcosa di simile e renderlo cliccabile usando jQuery. Al momento ho un semplice solo per test.Download file in Asp.Net MVC 2

Ho trovato una spiegazione per eseguire il download tramite un metodo di azione, ma sfortunatamente l'esempio aveva ancora link di azione.

Ora, posso chiamare il metodo di azione di download bene, ma non succede nulla. Credo di dover fare qualcosa con il valore di ritorno, ma non so cosa o come.

Ecco il metodo di azione:

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) 
     }; 
    } 

Ecco la classe 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(); 
    } 
} 

chiamo il metodo di azione tramite:

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

che è fatta cliccabile tramite:

$("#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? 
    }); 
}); 

Si noti che il parametro fileName viene ricevuto correttamente dal metodo di azione e tutto, è solo che non accade nulla quindi suppongo di dover gestire il valore restituito in qualche modo?

+0

La classe 'BinaryContentResult' non dovrebbe esistere. Usa 'FileResult'. – SLaks

+0

Ok, è una classe standard o qualcosa del genere? Come mi aiuterebbe a risolvere il problema? – Anders

risposta

4

Non si desidera scaricare il file utilizzando AJAX, si desidera che il browser lo scarichi. $ .get() lo preleverà ma non c'è modo di salvare localmente da Javascript, per ragioni di sicurezza il browser deve essere coinvolto. Basta reindirizzare al percorso di download e il browser lo gestirà per te.

+0

Ok, potresti specificare cosa intendi che dovrei fare per favore? Quello che voglio dire è che potrei usare semplici collegamenti per fare questo, come nell'esempio da cui ho preso questo, e la pagina non si ricaricherà, ma semplicemente aprirà una finestra di dialogo salva come. Voglio lo stesso comportamento, ma facendo clic sullo span (che determina quale file deve essere scaricato da una classe di selezione). Potresti specificare con un po 'di codice? Grazie! – Anders

+1

Utilizzare 'document.location.href = ...' per dire al browser di andare all'url per scaricare il file. Verrà visualizzata l'intestazione di disposizione del contenuto e verrà visualizzata come download non come pagina. –

+0

Perfetto! Ancora una domanda prima di chiudere questo problema: quando compare la finestra di dialogo save-as, ha il nome del file di tipo concatenato con caratteri di sottolineatura dal percorso e il nome del file, ad esempio: folder_folder_file.txt. Come mai? Voglio dire, il download funziona e tutto, ma voglio che abbia il suo nome di file originale. (Passando attraverso il metodo action e BinaryContentResult, la variabile FileName ha un percorso regolare: cartella \\ cartella \\ file.txt. Non riesco a capire dove questa concatenazione con caratteri di sottolineatura abbia luogo. Qualche idea? – Anders