2009-05-16 15 views
18

Potrzebuję wymusić zainicjowanie pobierania pliku .sql, gdy użytkownik kliknie przycisk w mojej aplikacji internetowej ASP .NET (C#).Wymuszenie pobrania pliku na serwerze WWW - ASP .NET C#

Jak w, po kliknięciu przycisku Zapisz jako okna powinny otwierać się na końcu klient ...

jaki sposób mogę to zrobić?

EDIT

Jest to kod używam

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

Jest to błąd, że jestem coraz ...

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

Co się stało?

+0

Państwo nie powinno się robić to tak, że w przypadku kliknięcia przycisku. Użyj Response.Redirect lub innych metod, aby przekierować użytkownika na inną stronę w zdarzeniu kliknięcia przycisku. Zobacz instrukcję w mojej odpowiedzi. –

Odpowiedz

29

utworzyć oddzielną Handler HTTP (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; } } 
} 

następnie dokonać tyłek na stronie ASP.NET przejdź do DownloadSqlFile.ashx.

+0

To jest lepsze niż moja odpowiedź pod względem wzorców projektowych. –

+5

Spowoduje to założenie, że plik, który chcesz pobrać, jest plikiem statycznym. –

+0

@TimJarvis W takim przypadku nie byłby to wcale plik. Byłby to po prostu strumień, który możesz wypisać za pomocą '.BinaryWrite()'. Po prostu nie zapomnij o "flush()" – tfrascaroli

18

Musisz poinformować przeglądarkę, że to, co wysyłasz, nie jest html i nie powinno być wyświetlane jako takie w przeglądarce. Poniższy kod może być użyty do powrotu jakiś tekst w kodzie strony serwera i przedstawi okno dialogowe Zapisz dla użytkownika, jak chcesz:

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: nazwę chcesz nadać mu

yourSQL: zawartość pliku sql

+0

Wystąpił błąd podczas robienia tego. dodano zrzut ekranu w poście. – Sameet

+0

Kopiuję ten kod ze strony, której używam, która pobiera dane .csv, więc wiem, że działa. Wzywam to w zdarzeniu page_load, być może Twoja strona już zaczęła wysyłać dane z powrotem do klienta? –

+0

Mój kod znajduje się w zdarzeniu button_click ... dlaczego musi być w page_laod()? Potrzebuję pobrania, aby rozpocząć wydarzenie jednym kliknięciem przycisku ... – Sameet

1

Dodaj Response.Clear przed Response.Write, aby naprawić błąd, o ile poprawnie zaznaczono w oknie przeglądarki Chrome.

więc integrować we fragmencie w innej odpowiedzi ...

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

Problem polega na tym, że używasz kodu na tej samej stronie co jest aktualnie załadowany w przeglądarce. Próbujesz zmodyfikować strumień odpowiedzi i dyspozycję aktualnej załadowanej strony. Zamiast tego utwórz osobny adres HttpHandler, zgodnie z sugestią Mehrdada. Następnie po kliknięciu przycisku wywołasz adres URL do obsługi. Może to być nawet prosty hiperlink, który zawiera następujący adres URL:

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

Czy masz sens? Chodzi o to, że nie można zmodyfikować odpowiedzi już załadowanej strony. Uruchom nową prośbę za pomocą programu obsługi, aby wykonać pracę.

0

Poniższa rozwiązanie działa dla mnie

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