2009-05-16 12 views
18

Ich muss die Initiierung des Downloads einer .SQL-Datei erzwingen, wenn der Benutzer auf eine Schaltfläche in meiner ASP.NET (C#) - basierten Webanwendung klickt.Download einer Datei auf Webserver erzwingen - ASP.NET C#

Wie in, wenn die Schaltfläche geklickt wird, ein als Speichern-Dialog auf der Clientseite öffnen soll ...

Wie mache ich das?

EDIT

Dies ist der Code, ich verwende

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

Dies ist der Fehler, ich bin immer ...

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

Was ist los?

+0

Sie sollten es nicht in Schaltfläche Click-Ereignis wie das tun. Verwenden Sie Response.Redirect oder andere Methoden, um den Benutzer auf eine andere Seite in Button-Click-Ereignis umzuleiten. Siehe die Anleitung in meiner Antwort. –

Antwort

29

einen separaten HTTP-Handler (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; } } 
} 

dann den Hintern machen In Ihrer ASP.NET-Seite navigieren Sie zu DownloadSqlFile.ashx.

+0

Das ist besser als meine Antwort in Bezug auf Design-Muster. –

+5

Dies setzt die Annahme voraus, dass die Datei, die Sie herunterladen möchten, eine statische Datei ist. –

+0

@TimJarvis In diesem Fall wäre es überhaupt keine Datei. Es wäre nur ein Stream, den Sie mit '.BinaryWrite()' ausgeben können. Vergiss nicht 'flush()' – tfrascaroli

18

Sie müssen dem Browser mitteilen, dass das, was Sie senden, kein HTML ist und nicht als solches im Browser angezeigt werden soll. Der folgende Code kann verwendet werden, um etwas Text in Ihrem serverseitigen Code zurück, und es wird die den Benutzer Dialog speichern präsentieren, wie man wollte:

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: der Name, den Sie wünschen, es zu

yourSQL: der Inhalt der sQL-Datei

+0

wird dabei ein Fehler angezeigt. einen Screenshot im Fragenpost hinzugefügt. – Sameet

+0

Ich kopiere diesen Code aus einer Seite, die ich verwende, die CSV-Daten herunterlädt, damit ich weiß, dass es funktioniert. Ich rufe es im page_load-Event an, vielleicht hat Ihre Seite bereits angefangen, Daten an den Client zurückzusenden? –

+0

Mein Code ist im button_click-Ereignis ... warum muss es in page_laod() sein? Ich brauche den Download, um auf einer Schaltfläche klicken Ereignis zu starten ... – Sameet

1

Fügen Sie eine Response.Clear vor Ihnen Response.Write hinzu, um den Fehler zu beheben, wenn dies im Chrome-Dialogfeld richtig angegeben ist.

So im Snippet in andere Antwort zu integrieren ...

//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

Das Problem ist, dass Sie den Code auf der gleichen Seite verwenden, wie sie derzeit in den Browser geladen wird. Sie versuchen, den Antwortstream und die Disposition der aktuell geladenen Seite zu ändern. Erstellen Sie stattdessen einen separaten HttpHandler, wie von Mehrdad vorgeschlagen. Mit einem Klick auf die Schaltfläche rufen Sie dann die URL zum Handler auf. Die Schaltfläche könnte sogar ein einfacher Hyperlink sein, der als Quell-URL folgende Adresse hatte:

Sinn machen? Der Punkt ist, Sie können die Antwort der bereits geladenen Seite nicht ändern. Starten Sie eine neue Anfrage mit einem Handler, um die Arbeit zu erledigen.

0

Die Lösung unten funktioniert für mich

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