如何:在不停止呈现页面的情况下从Web服务保存文件

本文关键字:情况下 Web 保存文件 服务 不停止 如何 | 更新日期: 2023-09-27 18:19:58

我有一个控制器,它有两个页面,索引和下载,当单击下载时,它会从服务中检索一个字节[],我使用Response.BinaryWrite来保存文件。问题是,当使用Response.Clear时,它会停止"下载"页面的呈现,但会成功下载文件。有没有办法下载文件并呈现页面?

我使用的是.NET 4,ASP,Monorail Castle,C#

我知道,通过使用MVC,我可以使用ActionResult和FileResult作为视图的返回类型,但我仅限于使用Monorail Castle,因为它是我最近拥有的现有项目,目前还没有改变它的技术。

下面是我的示例代码

public class MyController : Controller
{
    public void Index()
    {
        PropertyBag["includeZeroBalances"] = false;
        PropertyBag["toDate"] = DateTime.Today.ToShortDateString();
    }
    public void Download(bool includeZeroBalances, DateTime toDate)
    {
        MyProxy proxy = GetProxy();
        byte[] file = proxy.GetFile(includeZeroBalance, toDate);
        Response.Clear();
        Response.ContentType = "application/zip";
        Response.AppendHeader("Content-Disposition", "attachment; filename="TestFileName.zip");
        Response.BinaryWrite(file);
    }
}

这是的索引页

${Form.FormTag({@action: 'Download'})}
    <table>
        <tr>
            <td>${Form.LabelFor("toDate", "To Date (yyyy/mm/dd):")}</td>
            <td><input type="text" id="toDate" name="toDate" value="${?toDate}" /></td>
        </tr>
        <tr>
            <td>${Form.LabelFor("includeZeroBalances", "Include Zero Balances:")}</td>
            <td>${Form.CheckboxField("includeZeroBalances")}</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>${Form.Submit("Download", {@class: 'submitb'})}</td>
        </tr>
    </table>
${Form.EndFormTag()}

这是下载页面

<table>
    <tr>
        <td>Your file has been downloaded successfully</td>
    </tr>
</table>

如何:在不停止呈现页面的情况下从Web服务保存文件

正确的方法是使用多部分响应,不幸的是,有些浏览器不支持它们。

你能做的是像sourceforge和其他网站一样使用元刷新

  • 启动一个运行良好的文件下载,即使在IE中
  • 启动下载的最佳方式
  • 如何在Internet Explorer中启动文件的自动下载

我得到的答案并不像我希望的那样通用,但这个解决方案是有效的。

public class MyController : Controller
{
    public void Index()
    {
        PropertyBag["includeZeroBalances"] = false;
        PropertyBag["toDate"] = DateTime.Today.ToShortDateString();
    }
    public void Download(bool includeZeroBalances, DateTime toDate)
    {
        MyProxy proxy = GetProxy();
        byte[] file = proxy.GetFile(includeZeroBalance, toDate);
        PropertyBag["downloadurl"] = "data:application/zip;base64," + System.Convert.ToBase64String(file);
    }
}

这是的索引页

${Form.FormTag({@action: 'Download'})}
    <table>
        <tr>
            <td>${Form.LabelFor("toDate", "To Date (yyyy/mm/dd):")}</td>
            <td><input type="text" id="toDate" name="toDate" value="${?toDate}" /></td>
        </tr>
        <tr>
            <td>${Form.LabelFor("includeZeroBalances", "Include Zero Balances:")}</td>
            <td>${Form.CheckboxField("includeZeroBalances")}</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>${Form.Submit("Download", {@class: 'submitb'})}</td>
        </tr>
    </table>
${Form.EndFormTag()}

这是下载页面

<table>
    <tr>
        <td>Your file has been generated successfully. <a href="${downloadurl}">Click here</a> to download your file</td>
    </tr>
</table>

您还可以添加javascript来在新窗口中自动下载文件。

document.Ready(function()
{
    window.open("${downloadurl}");
});

使用此方法保存文件的优点:服务器上未保存任何文件。下载大约300kb以上的文件时开销略低您不会覆盖响应数据,因此视图将按照正常方式进行渲染。

使用此方法保存文件的缺点:通用性不足,无法在任何版本的浏览器上使用。如果用于静态文件,当文件更改时,由于文件内容嵌入在uri 中,因此必须再次生成uri

我希望这能帮助到其他似乎在同一问题上陷入困境的人。我在许多董事会上看到过这种类型的问题,但没有直接的解决方案。

相关文章: