【问题标题】:How to fix freezing page after file download?(TransmitFile in TreeView SelectedNodeChanged)文件下载后如何修复冻结页面?(TreeView SelectedNodeChanged中的TransmitFile)
【发布时间】:2017-03-08 12:52:41
【问题描述】:

所以我知道这是一个常见问题,页面冻结(任何按钮在视觉上都是可点击的,但不执行任何操作),因为它在文件下载后不会关闭某些请求。

System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/txt";
response.AddHeader("Content-Disposition", "attachment; filename=" + TreeView1.SelectedNode.Text + ";");
response.TransmitFile(TreeView1.SelectedNode.Value);
response.Flush();
response.Close();
HttpContext.Current.ApplicationInstance.CompleteRequest();

此代码在 TreeView SelectedNodeChanged 事件中,这是一个问题。

例如,如果将传输代码放在某个按钮中,我可以通过在按钮上添加 OnClientClick="javascript:setFormSubmitToFalse()" 来修复页面冻结问题,这个小 JavaScript 修复了下载后页面冻结问题。

<script type="text/javascript">
    //Fix page freeze after download dialog
    function setFormSubmitToFalse() {
        setTimeout(function () { _spFormOnSubmitCalled = false; }, 3000);
        return true;
    }
</script>

但如果我单击 TreeView 节点,我不知道如何解决此问题。 TreeView 没有OnClientClick,我也尝试在传输代码Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "setFormSubmitToFalse()", true); 之前和之后从后面的代码运行该JS 函数,但它没有帮助,文件下载后页面仍然冻结。

有什么想法可以解决这个问题吗?谢谢。

这是 sharepoint 网站上的 webpart(几乎是 asp.net 页面)。

编辑:

我将尝试更好地解释我的情况以及我想要实现的目标。

所以我的主要目标:在本地网络中有一个包含文档的共享文件夹,将使用此应用程序的用户不应访问此共享文件夹,只有运行应用程序池的实体才能访问它。

我正在发出一些 SQL 请求,它为我提供了一些子文件夹的路径。我正在构建该子文件夹的树视图,当用户单击树视图 SelectedNodeChanged 事件镜头中的某个文件时,我将文件作为应用程序池标识执行传输

SPSecurity.RunWithElevatedPrivileges(delegate()
   {
   /* transmit file code */
   }); 

一切正常,但如果我理解正确的话,CLIENT 端的某些东西可能会在 TransmitFile 拍摄后冻结页面并阻止向服务器发送任何其他发布请求,这就是为什么我的小 JS 解决方案在执行 OnClientClick 时有效。

这是该修复程序的作者如何解释的原始内容,但我不知道如何将其实现到树视图 https://stackoverflow.com/a/17186011/5805492

【问题讨论】:

  • 也许这个pagethis 对你有帮助。

标签: c# asp.net sharepoint treeview web-parts


【解决方案1】:

所以解决方案非常简单,但有点棘手。

Nodes 没有 onClientClick 事件,但是我们可以给任何页面元素添加 JS 点击事件,对吧?所以这里是诀窍,在创建 TreeView 时,只需在 Span 的帮助下将点击添加到节点的实际文本:

...
TreeNode fileNode = new TreeNode
 {
     //before
     //Text = file.Name,
     //after
     Text = "<span onclick=\"javascript:setFormSubmitToFalse();\">"+file.Name+"</span>",
     Value = file.FullName,
 };
...

并在传输文件时将节点的文本解析为正常的文件名:

response.AddHeader("Content-Disposition", "attachment; filename=" + 
    TreeView1.SelectedNode.Text.Replace("<span onclick=\"javascript:setFormSubmitToFalse();\">", string.Empty).Replace("</span>", string.Empty) + ";");

现在一切正常,下载后页面不再冻结。

【讨论】:

    【解决方案2】:

    我不确定我是否真的了解您的情况,但由于 UI 线程挂在您尝试同步运行的代码上,您的应用可能会被冻结。

    为了防止这种情况发生,您需要异步运行逻辑。

    public async void OnSelectedNodeChanged(object sender, EventArgs e)
    {
        await Task.Run(() => {
            System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
            response.ClearContent();
            response.Clear();
            response.ContentType = "text/txt";
            response.AddHeader("Content-Disposition", "attachment; filename=" + TreeView1.SelectedNode.Text + ";");
            response.TransmitFile(TreeView1.SelectedNode.Value);
            response.Flush();
            response.Close();
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }).ConfigureAwait(false);
    }
    

    这是一个异步 void 方法,这意味着触发此事件的代码不会等待它完成,也不会知道何时完成完成了。

    这将防止线程锁定您的 UI,但如果用户能够通过单击您的 UI 周围的所有区域来“快速触发”这些事件,则可能不希望以这种方式编写代码。

    无论如何,您可能需要一些形式的异步逻辑来完成您想要的。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多