2009-05-16 14 views
18

È necessario forzare l'avvio del download di un file .sql, quando l'utente fa clic su un pulsante nella mia applicazione Web ASP .NET (C#).Download forzato di un file sul server Web - ASP .NET C#

Come in, quando il pulsante viene premuto, una finestra di dialogo Salva dovrebbe aprire alla fine del cliente ...

Come posso fare questo?

EDIT

Questo è il codice che sto usando

 string sql = ""; 
     using (System.IO.StreamReader rdr = System.IO.File.OpenText(fileName)) 
     { 
      sql = rdr.ReadToEnd(); 
     } 
     Response.ContentType = "text/plain"; 
     Response.AddHeader("Content-Disposition", "attachment; filename=Backup.sql"); 
     Response.Write(sql); 
     Response.End(); 

Questo è l'errore che sto ricevendo ...

alt text http://img40.imageshack.us/img40/2103/erroro.gif

Cosa c'è di sbagliato?

+0

non si dovrebbe essere fatto in quel modo in evento click del pulsante. Utilizzare Response.Redirect o altri metodi per reindirizzare l'utente a un'altra pagina nell'evento clic del pulsante. Vedi le istruzioni nella mia risposta. –

risposta

29

creare un gestore HTTP separata (DownloadSqlFile.ashx):

<%@ WebHandler Language="C#" Class="DownloadHandler" %> 

using System; 
using System.Web; 

public class DownloadHandler : IHttpHandler { 
    public void ProcessRequest(HttpContext context) { 
     var fileName = "myfile.sql"; 
     var r = context.Response; 
     r.AddHeader("Content-Disposition", "attachment; filename=" + fileName); 
     r.ContentType = "text/plain"; 
     r.WriteFile(context.Server.MapPath(fileName)); 
    } 
    public bool IsReusable { get { return false; } } 
} 

poi fare il calcio nella pagina ASP.NET passare a DownloadSqlFile.ashx.

+0

Questo è meglio della mia risposta in termini di modelli di progettazione. –

+5

Questo presuppone che il file che si desidera scaricare sia un file statico. –

+0

@TimJarvis In tal caso non sarebbe affatto un file. Sarebbe solo un flusso che è possibile produrre con '.BinaryWrite()'. Basta non dimenticare di 'flush()' – tfrascaroli

18

È necessario comunicare al browser che ciò che si sta inviando non è html e non deve essere visualizzato come tale nel browser. Il seguente codice può essere utilizzato per restituire un po 'di testo nel codice lato server e presenterà la finestra di dialogo per l'utente come si voleva risparmiare:

Response.Clear(); //eliminates issues where some response has already been sent 
Response.ContentType = "text/plain"; 
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.sql", filename)); 
Response.Write(yourSQL); 
Response.End(); 

filename: il nome che si desidera dare

yourSQL: il contenuto del file sql

+0

ottenendo un errore su questo. aggiunto uno screenshot nel post della domanda. – Sameet

+0

Sto copiando quel codice da una pagina che uso che scarica i dati .csv quindi so che funziona. Lo chiamo nell'evento page_load, forse la tua pagina ha già iniziato a inviare dati al client? –

+0

Il mio codice è nell'evento button_click ... perché deve essere in page_laod()? Ho bisogno del download per iniziare su un evento clic sul pulsante ... – Sameet

1

Aggiungere un Response.Clear prima di Response.Write per correggere l'errore, se indicato correttamente nella finestra di dialogo di Chrome.

Quindi, per integrare nel frammento in altra risposta ...

//add this 
Reponse.Clear(); 

//from other answer 
Response.ContentType = "text/plain"; 
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.sql", filename)); 
Response.Write(yourSQL); 
Response.End; 
5

Il problema è che si sta utilizzando il codice sulla stessa pagina, come è attualmente caricata nel browser. Stai tentando di modificare il flusso di risposta e la disposizione della pagina caricata corrente. Invece, crea un HttpHandler separato, come suggerito da Mehrdad. Quindi, con il clic del pulsante, invocherai l'URL al gestore. Il pulsante potrebbe anche essere un semplice collegamento ipertestuale che ha il seguente URL di origine:

<a href="DownloadSqlFile.ashx">Download SQL</a> 

Ha senso? Essendo il punto, , non è possibile modificare la risposta della pagina già caricata. Avvia una nuova richiesta utilizzando un gestore per eseguire il lavoro.

0

La soluzione qui di seguito funziona per me

string fileNameAndExtension = "thisFile.pdf";  
string fullPath = "../folder/files/" + fileNameAndExtension;  
Response.Clear(); 
Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileNameAndExtension); 
Response.TransmitFile(fullPath); 
Response.End();