【问题标题】:Forcing A Postback Asp.Net强制回发 Asp.Net
【发布时间】:2011-02-18 16:40:29
【问题描述】:

请看下面的点击事件...

Protected Sub btnDownloadEmpl_Click(ByVal sender As Object, ByVal e As System.EventArgs) 处理 btnDownloadEmpl.Click 将 emplTable 调暗为 DataTable = SiteAccess.DownloadEmployee_H() Dim d As String = Format(Date.Now, "d") 暗淡 ad() As String = d.Split("/") Dim fd As String = ad(0) & ad(1) Dim fn As String = "E_" & fd & ".csv" Response.ContentType = "文本/csv" Response.AddHeader("Content-Disposition", "attachment; filename=" & fn) CreateCSVFile(emplTable, Response.Output) Response.Flush() 响应结束() lblEmpl.Visible = True 结束子

此代码只是将数据从数据表导出到 csv 文件。这里的问题是 lblEmpl.Visible=true 永远不会被击中,因为此代码不会导致回发到服务器。即使我将代码行 lblEmpl.Visible=true 放在单击事件的顶部,该行也可以正常执行,但页面永远不会更新。我怎样才能解决这个问题?

【问题讨论】:

标签: c# asp.net vb.net


【解决方案1】:

这一行:

lblEmpl.Visible = True

永远不会被击中,因为这条线:

Response.End()

抛出ThreadAbortException

我认为一种更简洁的处理方法是创建一个简单的 HttpHandler 组件,并在弹出窗口中“打开”它。 (弹出窗口实际上不应该打开。在大多数情况下,浏览器会意识到它实际上是一个下载,并会抑制选项卡/窗口。)

研究IHttpHandler 接口。它们实际上很容易实现。

这是一个示例处理程序。抱歉,拖了一会儿,我被叫去开会:

public class CensusHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string fileName = String.Format(
            CultureInfo.CurrentUICulture,
            "E_{0:00}{1:00}.csv",
            DateTime.Today.Month,
            DateTime.Today.Day
            );

        context.Response.ContentType = "text/csv";
        context.Response.AddHeader(
            "Content-Disposition", String.Format(null, "attachment; filename={0}", fileName)
            );

        //Dump the CSV content to context.Response

        context.Response.Flush();
    }

    public bool IsReusable { get { return false; } }
}

好的,尝试添加一个javascript onclick事件来触发下载:

<asp:Button ID="Clickety" runat="server" Text="Click Me!" OnClick="Clickety_Click"
    OnClientClick="window.open('Handler.ashx', 'Download');" />

常规的OnClick 事件将触发您的回发代码。 javascript onclick (OnClientClick) 事件将通过HttpHandler 启动下载。

【讨论】:

  • 如果我不把 Response.End 行放在那里会有什么效果。有缺点吗?
  • 即使我将 Response.End 行注释掉,它仍然不起作用。
  • 我正在网上搜索,但不确定您的意思。我以前从未使用过 HttpHandler。你能给我举个很好的例子吗?
  • 我如何使用那个东西。我不知道,我一直在研究这些处理程序并且完全迷失了。
  • 试试这个。将“通用处理程序”项添加到您的 Web 应用程序,并使用上面的代码。在我有 Dump the CSV... 评论的地方,输入 context.Response.WriteLine("Hello World!"); 现在在浏览器中打开 .ashx 模块并关注发生的情况。
【解决方案2】:

您正在将 CSV 发送到响应流,然后结束它。因此,一旦您的所有代码都运行完毕,页面本身就不再被发送到响应流中,因此也不会在浏览器中更新。

为了实现你的目标,你需要创建第二个响应流。最简单的方法是通过新的浏览器窗口/弹出窗口。然后您的 CSV 可以在弹出窗口中下载,并且您的初始页面响应可以保留在初始浏览器中。

【讨论】:

    【解决方案3】:

    只需在 Page_Load 上使用此代码创建一个新页面

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) 
        Dim emplTable As DataTable = SiteAccess.DownloadEmployee_H()
        Dim d As String = Format(Date.Now, "d")
        Dim ad() As String = d.Split("/")
        Dim fd As String = ad(0) & ad(1)
        Dim fn As String = "E_" & fd & ".csv"
        Response.ContentType = "text/csv"
        Response.AddHeader("Content-Disposition", "attachment; filename=" & fn)
        CreateCSVFile(emplTable, Response.Output)
        Response.Flush()
        Response.End()
    End Sub
    

    然后在您的原始页面上使您的 lblEmpl 不可见并注册如下脚本以使用您的 csv 打开一个新窗口。

    var csvPageJS = string.Format("window.open ('{0}','mywindow');", ResolveUrl("~/MyCSVPage.aspx"));
      ClientScript.RegisterStartupScript(typeof(Page), "popup", csvPageJS, true);
    

    【讨论】:

    • 我试过它不起作用。它会下载数据,但不会刷新页面上的控件。
    • 那个代码有点用。唯一的问题是它在使标签可见之前更新页面然后打开对话框。尽管我说过要在脚本运行后使标签可见。 Dim csvPageJS As String = String.Format("window.open ('{0}','mywindow');", ResolveUrl("~/TESTLOAD.aspx")) ClientScript.RegisterStartupScript(GetType(Page), "popup" , csvPageJS, True) lblRG.Visible = True
    • 尝试使用更新面板,这样您就不会注意到页面加载,只需确保将 ClientScript.RegisterStartupScript 更改为 ScriptManager.RegisterStartupScript 以使其与异步回发一起使用
    【解决方案4】:

    您应该使用弹出窗口,以便您仍然可以在原始页面上设置标签。据我所知,你可以做这样的事情

    1. 为弹出窗口创建一个单独的表单以创建 CSV,将您的函数移动到新 page.cs 的加载中,并向其发送一个查询字符串参数,以便其 dataID 导出。

      Protected Sub onLoad()
          Dim recordID As Integer = Request.Querystring("dID")
          Dim emplTable As DataTable = Nothing 
          Select Case recordID 
            case 1: emplTable = SiteAccess.DownloadEmployee_H() 
            case 2: emplTable = SiteAccess.DownloadManagers() 
          End Select 
          Response.Clear()
          Response.ContentType = "text/csv"
          Response.AddHeader("Content-Disposition", "attachment; filename=" & fn)
          CreateCSVFile(emplTable, Response.Output)
          Response.Flush()
          Response.End() 
          lblEmpl.Visible = True
      End Sub
      
    2. 从按钮的 onClientClick 属性启动弹出窗口,或在回发中注册一个脚本。

      function fnPopUpCSV(expType)
      {        
      window.open('/popUpPage.aspx?dID=' + expType,'CSVwindow', 
      'width=300,height=200,menubar=yes,status=yes,
      location=yes,toolbar=yes,scrollbars=yes');
      }
      
      <asp:Button ID="btnGenEmplCSV" runat="server" Text="Generate Employee CSV"
      onClientClick="javascript:return fnPopUpCSV(1);" />
      
      <asp:Button ID="btnGenMgrCSV" runat="server" Text="Generate Manager CSV"
      onClientClick="javascript:return fnPopUpCSV(2);" />
      

    【讨论】:

    • 感谢您的帮助。你能告诉我更多细节吗?我不是这方面的专业人士。我会这样做来添加缺失的部分吗? Dim emplTable As DataTable =Nothing Select Case recordID case 1: emplTable = SiteAccess.DownloadEmployee_H() case 2: emplTable = SiteAccess.DownloadManagers() End Select
    • 如果你只有两种获取数据的方法,我猜你不需要花哨。我刚刚编辑了示例以将代码放入 2 个按钮中,并将 js 函数更改为通过 args。我也将您的选择案例添加到服务器代码中。希望对您有所帮助。
    • 在您的情况下,我不确定主页是否可以看到 lblEmpl.Visible = True。如果我正确地跟随你,这就是我得到的。例如,在主页上,我有名为 DownloadEmployee 的按钮(7 个不同的 csv,7 个按钮)。我在该单击事件中单击按钮,它运行 fnPopUp 并转到另一个页面并下载,但标签在主页上而不是弹出页面上,因此它不会看到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    相关资源
    最近更新 更多