【问题标题】:Post Back does not work after writing files to response in ASP.NET在 ASP.NET 中写入文件以响应后回发不起作用
【发布时间】:2011-01-21 04:01:51
【问题描述】:

我有什么?

我有一个 ASP.NET 页面,它允许用户通过单击按钮下载文件 a。用户可以从可用文件列表(RadioButtonList)中选择他想要的文件,然后单击下载按钮进行下载。 (我不应该为每个可以下载的文件提供链接 - 这是要求)。

我想要什么?

我希望用户通过选择所需的单选按钮并单击该按钮来一一下载多个文件。

我面临什么问题?

我第一次可以正常下载文件。但是,下载后,如果我选择其他文件并点击按钮下载它,按钮的点击事件不会回发,第二个文件也不会下载。

我在按钮点击事件上使用如下代码:

protected void btnDownload_Click(object sender, EventArgs e)
{
    string viewXml = exporter.Export();
    Response.Clear();
    Response.AddHeader("Content-Disposition", "attachment; filename=views.cov");
    Response.AddHeader("Content-Length", viewXml.Length.ToString());
    Response.ContentType = "text/plain";
    Response.Write(viewXml);
    Response.End();
}

我在这里做错了吗?

同样的问题可以在 IE6、IE7 和 Chrome 中复制。我认为这个问题与浏览器无关。

【问题讨论】:

  • 如果您在启用 Ajax 的表单(或控件)上,则可能是 Ajax javascript 被混淆或阻塞,因为您返回了不同的文档而不是返回 Javascript 所期望的(一些视图状态信息加上更新的 html 进入更新面板)。另见social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/…

标签: asp.net download


【解决方案1】:

我在使用 sharepoint 时遇到了同样的问题。我在页面上有一个发送文件的按钮,单击该按钮后,表单的其余部分没有响应。事实证明,将变量 _spFormOnSubmitCalled 设置为 true 以防止任何进一步的提交是一个共享点。当我们发送文件时,这不会刷新页面,因此我们需要手动将此变量设置回 false。

在 Web 部件中的按钮上,将 OnClientClick 设置为页面 javascript 中的函数。

 <asp:Button ID="generateExcel" runat="server" Text="Export Excel" 
OnClick="generateExcel_Click" CssClass="rptSubmitButton"
OnClientClick="javascript:setFormSubmitToFalse()" />

然后在javascript中我有这个功能。

function setFormSubmitToFalse() {
    setTimeout(function () { _spFormOnSubmitCalled = false; }, 3000);
    return true;
}

我发现 3 秒的暂停是必要的,因为否则我在 sharepoint 设置变量之前设置它。这样,我让 sharepoint 正常设置它,然后我立即将其设置回 false 。

【讨论】:

  • 我以前知道这个花絮,但我完全忘记了。感谢您通过提醒我节省了我的时间。
  • 对我的 sharepoint 文档库 > 文档下载问题很有帮助。三声欢呼!!!
  • 非常感谢,它成功了。但现在是否存在允许用户在单击按钮后重新提交表单的安全漏洞?
【解决方案2】:

副手,你正在做的应该工作。尽管我使用了中继器和 LinkBut​​tons,但我过去也成功地做过类似的事情。

我能看到的唯一不同之处在于您使用的是Response.Write() 而不是Response.OutputStream.Write(),并且您正在编写文本而不是二进制文件,但是鉴于您指定的ContentType,它不应该是个问题。此外,我在发送信息之前拨打Response.ClearHeaders(),之后拨打Response.Flush()(在我拨打Response.End()之前)。

如果有帮助,这里有一个对我有用的净化版本:

// called by click handler after obtaining the correct MyFileInfo class.
private void DownloadFile(MyFileInfo file) 
{
    Response.Clear();
    Response.ClearHeaders();
    Response.ContentType = "application/file";
    Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.FileName + "\"");
    Response.AddHeader("Content-Length", file.FileSize.ToString());
    Response.OutputStream.Write(file.Bytes, 0, file.Bytes.Length);
    Response.Flush();
    Response.End();        
}

您可能需要考虑以二进制方式传输文件,可能通过调用System.Text.Encoding.ASCII.GetBytes(viewXml); 并将结果传递给Response.OutputStream.Write()。

稍微修改你的代码:

protected void btnDownload_Click(object sender, EventArgs e)
{
    string viewXml = exporter.Export();
    byte [] bytes = System.Text.Encoding.ASCII.GetBytes(viewXml); 
    // NOTE: you should use whatever encoding your XML file is set for.
    // Alternatives:
    // byte [] bytes = System.Text.Encoding.UTF7.GetBytes(viewXml);
    // byte [] bytes = System.Text.Encoding.UTF8.GetBytes(viewXml);

    Response.Clear();
    Response.ClearHeaders();
    Response.AddHeader("Content-Disposition", "attachment; filename=views.cov");
    Response.AddHeader("Content-Length", bytes.Length.ToString());
    Response.ContentType = "application/file";
    Response.OutputStream.Write(bytes, 0, bytes.Length);
    Response.Flush();
    Response.End();
}

【讨论】:

  • 谢谢,兰多夫。修改后的代码也没有运气。它的行为相同:(
  • 嗯...好吧,我很难过。就像我说的,我所拥有的一切都很好。在调用单击处理程序之前,是否有可能是您在代码中执行的操作?如果可以,请尝试发布整个页面和代码隐藏。
  • Response.ClearHeaders() 对我来说似乎很关键。谢谢兰多夫。
【解决方案3】:

不删除Response.End 的简单方法是添加客户端js 来进行页面刷新。将 js 添加到按钮的 onclientclick 属性中。

例如

    onclientclick="timedRefresh(2000)"

then in your html..

    <script type="text/JavaScript">
    <!--
    function timedRefresh(timeoutPeriod) {
        setTimeout("location.reload(true);",timeoutPeriod);
    }
    //   -->

【讨论】:

    【解决方案4】:

    删除Response.End(),让响应在 ASP.NET 生态系统内自然结束。

    如果这不起作用,我建议将按钮放在单独的 &lt;form&gt; 中,并将所需的数据发布到单独的 HTTP 处理程序。设置 HTTP 处理程序以导出 XML 而不是网页。

    【讨论】:

    • 最初我没有包含Response.End()。那时它也不起作用!
    • 嗯。好吧,也许您可​​以尝试将按钮放在单独的&lt;form&gt; 中并将所需数据发布到设置为导出 XML 的单独 HTTP 处理程序?
    • 另外,您应该指定一个内容编码,如Response.ContentEncoding = Encoding.UTF8
    • 乔希,谢谢你的建议。我可以使用 HTTP 处理程序来完成任务。你能把它作为答案,以便我标记它吗?
    【解决方案5】:

    我有同样的问题。在 aspx 页面上的按钮单击事件上执行简单 Response.Writer("") 的函数从未触发。

    类中的方法:

    public test_class()
    {
        public test_class() { }
    
        public static void test_response_write(string test_string) 
        {
            HttpContext context = HttpContext.Current;
            context.Response.Clear();
            context.Response.Write(test_string);
            context.Response.End();                   
        }
    }
    

    ASPX 页面:

    protected void btn_test_Click(object sender, EventArgs e)
    {
        test_class.test_response_write("testing....");
    }
    

    当我试图找出原因时,我只是在 Page_Load 事件上调用了相同的函数,它起作用了。

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            test_class.test_response_write("testing....");
        }
    }
    

    调查问题后,我发现该 aspx 页面正文的母版页位于 &lt;asp:UpdatePanel&gt; 下。

    我删除了它,它在Button_Click Event 上运行。我建议你也检查一下。

    【讨论】:

      【解决方案6】:

      查看https://multilingualdev.wordpress.com/2014/08/19/asp-net-postback-after-response-write-work-around-solution/

      在向客户端发送文件并在 ASP.Net 中使用 response.write 时,开发人员在发送文件后无法执行任何其他操作。还有其他变通方法,例如添加 javascript onclick 函数,该函数将在客户端获取文件后调用函数,这类似于在调用发送文件的函数时添加元刷新(例如 Response.AppendHeader(“刷新”、“5;URL=” & HttpContext.Current.Request.Url.AbsoluteUri))

      但那些并没有给我想要的外观。所以我结合了这些变通方法来提出这个解决方案:

      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      
      checkSendFile() ‘each time page loads it will check to see if it needs to send the file
      
      If (Not IsPostBack) Then
      
      ‘this spot is not be executed after a form submit (postback); which means you can put 
      
      ‘ the checkSendFile() in here if you want
      
      end If
      
      End Sub
      
      Private Sub checkSendFile()
      
      Dim sendFile As String = Session(“SENDFILE”) ‘ first we get the session file to see if its time 
      
      ‘ to send a file
      
      If Not sendFile Is Nothing Then
      
      If sendFile = “YES” Then
      
      Session(“SENDFILE”) = “” ‘here we clear the session file so it doesn’t send again if
      
      ‘ refreshed
      
      sendClientFile() ‘ function to send the file to client
      
      End If
      
      End If
      
      End Sub
      
      Protected Sub btnGetFile_Click(sender As Object, e As EventArgs) Handles btnGetFile.Click
      
      ‘this is where the client clicks on a button or link or something that submits the form and 
      
      ‘ request a file to be sent to them
      
      Session(“SENDFILE”) = “YES” ‘ we set a session variable flag 
      
      ‘then we update the GUI, or run any other method that we wanted to do after client gets file
      
      me.lblMsgToClient.text = “Thank you for downloading file.”
      
      RefreshPage() ‘ then we refresh the page instantly (this is where post back will update values
      
      ‘ and interface, then send file)
      
      End Sub
      
      Private Sub RefreshPage()
      
      ‘ here we instantly add a refresh meta tag to the header with zero seconds to refresh to the
      
      ‘ same url we are currently at
      
      Response.AppendHeader(“Refresh”, “0;URL=” & HttpContext.Current.Request.Url.AbsoluteUri)
      
      End Sub
      
      Private Sub sendClientFile()
      
      ‘here you will have your file and bytes to send to browser from either file system or database
      
      ‘then you can call sendToBrowser(…)
      
      End Sub
      
      Private Sub sendToBrowser(ByVal fileName As String, ByVal contentType As String, ByRef fileBytes As Byte())
      
      ‘this function is just the normal send file to client
      
      Response.AddHeader(“Content-type”, contentType)
      Response.AddHeader(“Content-Disposition”, “attachment; filename=” & fileName)
      Response.BinaryWrite(fileBytes)
      Response.Flush()
      Response.End()
      
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        • 2018-03-27
        • 2012-03-31
        相关资源
        最近更新 更多