【问题标题】:Force download of a file on web server - ASP .NET C#强制在 Web 服务器上下载文件 - ASP .NET C#
【发布时间】:2009-05-16 20:19:05
【问题描述】:

当用户单击基于 ASP .NET (C#) 的 Web 应用程序中的按钮时,我需要强制启动 .sql 文件的下载。

如单击按钮时,应在客户端打开另存为对话框...

我该怎么做?

编辑

这是我正在使用的代码

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

这是我遇到的错误...

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

怎么了?

【问题讨论】:

  • 你不应该在按钮的点击事件中那样做。使用 Response.Redirect 或其他方法在按钮单击事件中将用户重定向到另一个页面。请参阅我的回答中的说明。

标签: c# asp.net download


【解决方案1】:

创建一个单独的 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; } }
}

然后让 ASP.NET 页面中的按钮导航到 DownloadSqlFile.ashx

【讨论】:

  • 就设计模式而言,这比我的回答要好。
  • 这确实假设您要下载的文件是静态文件。
  • @TimJarvis 在这种情况下,它根本就不是文件。它只是一个可以使用.BinaryWrite() 输出的流。只是不要忘记flush()
【解决方案2】:

你需要告诉浏览器你发送的不是 html 并且不应该在浏览器中显示。以下代码可用于在您的服务器端代码中返回一些文本,它会根据您的需要向用户显示保存对话框:

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: 你想给它起的名字

yourSQL:sql文件的内容

【讨论】:

  • 执行此操作时出错。在问题帖子中添加了屏幕截图。
  • 我正在从我使用的用于下载 .csv 数据的页面中复制该代码,因此我知道它可以正常工作。我在 page_load 事件中调用它,也许你的页面已经开始向客户端发送数据了?
  • 我的代码在 button_click 事件中...为什么它需要在 page_laod() 中?我需要在按钮单击事件上开始下载...
  • 看看 Mehrdad 对您上面的问题的评论,他是对的,做一个 response.redirect 到一个专门的页面。我意识到我用来下载的页面只是查看请求字符串来计算出我需要返回的项目的 id,并且它在页面上根本没有控件。另请参阅 mehrdad 的答案,他给出了比我更好的答案 - httphandler 是更好的做法。
【解决方案3】:

问题是您正在使用浏览器中当前加载的同一页面上的代码。您正在尝试修改当前加载页面的响应流和配置。 相反,请按照 Mehrdad 的建议创建一个单独的 HttpHandler。然后单击按钮,您将调用处理程序的 URL。该按钮甚至可以是一个简单的超链接,其源 URL 如下:

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

有意义吗?重点是,您不能修改已加载页面的响应。使用处理程序启动新请求以完成工作。

【讨论】:

    【解决方案4】:

    如果在 Chrome 对话框中正确说明,请在 Response.Write 之前添加 Response.Clear 以修复错误。

    所以要在其他答案中集成 sn-p...

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

      以下解决方案对我有用

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-12
        • 1970-01-01
        • 2013-07-18
        • 1970-01-01
        • 2012-08-10
        • 1970-01-01
        • 1970-01-01
        • 2019-01-07
        相关资源
        最近更新 更多