2009-05-16 7 views
18

Necesito forzar la iniciación de la descarga de un archivo .sql, cuando el usuario hace clic en un botón en mi aplicación web ASP .NET (C#).Descargue la fuerza de un archivo en el servidor web - ASP .NET C#

igual que en, al hacer clic en el botón, un diálogo Guardar como debe abrir en el extremo del cliente ...

¿Cómo se hace esto?

EDITAR

Este es el código que estoy utilizando

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

Este es el error que estoy recibiendo ...

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

¿Qué ocurre?

+0

no deberías estar haciéndolo así en evento de clic de botón. Use Response.Redirect u otros métodos para redirigir al usuario a otra página en el evento de clic de botón. Ver las instrucciones en mi respuesta. –

Respuesta

29

crear un controlador HTTP independiente (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; } } 
} 

luego hacer la culata en su página ASP.NET navegue al DownloadSqlFile.ashx.

+0

Esto es mejor que mi respuesta en términos de patrones de diseño. –

+5

Esto supone que el archivo que desea descargar es un archivo estático. –

+0

@TimJarvis En ese caso, no sería un archivo en absoluto. Simplemente sería una secuencia que puede generar con '.BinaryWrite()'. Solo no te olvides de 'flush()' – tfrascaroli

18

Debe decirle al navegador que lo que está enviando no es html y no debe mostrarse como tal en el navegador. El código siguiente se puede utilizar para volver algún texto en el código del lado del servidor y se presentará el cuadro de diálogo para el usuario, ya que queríamos guardar:

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: el nombre que desea darle

yourSQL: los contenidos del archivo sql

+0

obteniendo un error al hacer esto. agregó una captura de pantalla en la publicación de la pregunta. – Sameet

+0

Copio ese código de una página. Utilizo ese archivo de datos .csv para que sepa que funciona. Lo llamo en el evento page_load, ¿quizás su página ya comenzó a enviar datos al cliente? –

+0

Mi código está en el evento button_click ... ¿por qué necesita estar en page_laod()? Necesito la descarga para comenzar con un evento de clic de botón ... – Sameet

1

Agregue Response.Clear antes que Response.Write para corregir el error, si se indica correctamente en el cuadro de diálogo de Chrome.

Así que para integrar en el fragmento de otra respuesta ...

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

El problema es que usted está utilizando el código en la misma página que se carga actualmente en el navegador. Está intentando modificar la secuencia de respuesta y la disposición de la página cargada actual. En su lugar, cree un HttpHandler por separado, como lo sugiere Mehrdad. Luego, al hacer clic en el botón, invocará la URL al controlador. El botón podría incluso ser un hipervínculo simple que tenía la siguiente URL fuente:

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

¿Tiene sentido? El punto es que no puede modificar la respuesta de la página ya cargada. Inicie una nueva solicitud utilizando un controlador para hacer el trabajo.

0

La solución a continuación funciona para mí

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