c# - 从静态方法调用 Response.TransmitFile()

标签 c# asp.net response

我有许多页面需要支持将数据导出到 Excel 电子表格。我可以很好地生成 Excel 文件,但我正在尝试弄清楚如何抽象出这种行为,以便它可以很容易地从我需要它的所有页面中重用。我目前的想法是使用静态实用方法,如下:

public static void SendExcelFile(System.Web.UI.Page callingPage, string downloadFileName, List<List<string>> data, string worksheetTitle)
{
    string tempFileName = Path.GetTempFileName();

    try
    {
        // Generate file using ExcelPackage
        GenerateExcelDoc(tempFileName, data, worksheetTitle);

        callingPage.Response.AddHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
        callingPage.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        callingPage.Response.AddHeader("Content-Length", new FileInfo(tempFileName).Length.ToString());
        callingPage.Response.TransmitFile(tempFileName);
    }
    finally
    {
        //When this is removed, the method works as expected.
        if (File.Exists(tempFileName))
            File.Delete(tempFileName);  
    }
}

我调用 SendExcelFile 的点击处理程序如下所示:

protected void lnkExport_Click(object sender, EventArgs e)
{
    List<List<string>> dataList = GatherDataForSpreadsheet();
    Utility.SendExcelFile(this, "fileNameForDownload.xlsx", dataList, "MyReports");
}

此代码作为调用页面的实例方法工作得很好。但是,作为静态方法,它根本不起作用。当我单击调用它的按钮时,浏览器无限期地显示加载动画,但从不提示下载文件。

我对 ASP.NET(和一般的 Web 编程)还很陌生,所以我确定我在这里遗漏了一些东西。有人可以解释我所看到的行为,并提出一种合理的替代方法吗?

编辑:如果我在最后删除对 File.Delete() 的调用,该方法将按预期工作。 Response.TransmitFile() 是否异步进行传输?

编辑 2:我只需要在删除文件之前调用 Response.Flush()。请参阅下面的答案。 谢谢!

最佳答案

问题是临时文件在数据发送之前被删除了。我只需要像这样调用 Response.Flush() :

public static void SendExcelFile(System.Web.UI.Page callingPage, string downloadFileName, List<List<string>> data, string worksheetTitle)
{
    string tempFileName = Path.GetTempFileName();

    try
    {
        // Generate file using ExcelPackage
        GenerateExcelDoc(tempFileName, data, worksheetTitle);

        callingPage.Response.AddHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
        callingPage.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        callingPage.Response.AddHeader("Content-Length", new FileInfo(tempFileName).Length.ToString());
        callingPage.Response.TransmitFile(tempFileName);
        callingPage.Response.Flush();  //This is what I needed
    }
    finally
    {
        if (File.Exists(tempFileName))
            File.Delete(tempFileName);  
    }
}

关于c# - 从静态方法调用 Response.TransmitFile(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2275894/

相关文章:

c# - 找不到类型或命名空间名称

c# - 如何在 MVC 5 项目中使用 Json.NET 进行 JSON 模型绑定(bind)?

c# - 尝试将数据从 WPF 应用程序发送到任何 Web 浏览器上的网页

node.js - NodeJ发送后无法设置头

c# - 初始化接口(interface)中的值

c# - 自定义代码片段

c# - ASP.NET MVC 5 为下拉列表设置值

asp-classic - 写入后是否可以更改经典的 ASP 响应?

http - 发送 HTTP 请求告诉服务器只返回 header 而不返回正文?

c# - 已发布的控制台应用程序上没有 .NET Core 2.0 应用程序设置