【问题标题】:Download feature not working within update panel in asp.net下载功能在 asp.net 的更新面板中不起作用
【发布时间】:2011-07-24 14:36:25
【问题描述】:

我有一个包含 FormView 的 Web 用户控件。 formview 显示求职者的详细信息。我为“下载简历”链接提供了一个按钮,以便管理员/HR 可以下载简历。我已将此控件放置在包含 UpdatePanel 的 aspx 页面中。除下载链接外,一切正常。

我已经给出了一个关于下载链接按钮的命令,并且一个函数与该命令相关联以开始下载。

下面是我实现的代码-

//Command on 'Download' link button within FormView
protected void lnkDownload_Command(object sender, CommandEventArgs e)
{
    if (e.CommandName.Equals("Download"))
    {
        StartDownload(e.CommandArgument.ToString());
    }
}

//My routine to download document
//sFileInfo contains filepath$==$mimetype
protected void StartDownload(string sFileInfo)
{
    string[] d = sFileInfo.ToString().Split((new string[] { "$==$" }), StringSplitOptions.None);
    string filename = d[0];
    string docType = d[1];

    System.IO.FileInfo file = new System.IO.FileInfo(d[0]);

    if (file.Exists)
    {
        Response.Clear();
        Response.AddHeader("Content-Disposition", "attachment; filename=" + d[0]);
        Response.AddHeader("Content-Length", file.Length.ToString());
        Response.ContentType = d[1];
        Response.WriteFile(file.FullName);
        Response.End();
    }
    else
    {
        Server.Transfer("~/Mesgbox.aspx?cat=2");
    }
}

如果更新面板被删除,代码可以完美运行,但如果使用更新面板,则会生成脚本错误。

有什么建议吗....?

感谢您分享您的时间。

【问题讨论】:

  • 您是否在页面中添加了 asp:ScriptManager?
  • 你找到解决这个问题的方法了吗?

标签: c# asp.net ajax


【解决方案1】:

要启动整页回发,请将回发触发器添加到更新面板:

<asp:UpdatePanel runat="server">
    <Triggers>
        <asp:PostBackTrigger ControlID="YourControlID" />
    </Triggers>
    <ContentTemplate>
        .....

【讨论】:

  • 以上问题是关于用户控制的,我在哪里可以添加触发器?
  • 如果您尝试使用 Response 下载文件,这不会回答
  • @MichaelRudnerEvanchik - 它回答“下载功能在 asp.net 的更新面板中不起作用”键是 PostBackTrigger 而不是 AsyncPost .....谢谢 Mitul
【解决方案2】:

您不能在 UpdatePanel 部分回发中返回附件,因为 ScriptManager 使用结果来更新 DIV(而不是整个响应)。最简单的解决方法是将下载按钮设置为回发控件。这将导致该按钮启动完整的回发。下面是要包含在 Page_Load 中的代码

ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(this.lnkDownload);

【讨论】:

  • 我每次都忘记这一点 - 为将来参考添加书签...比尝试将我的所有 UpdatePanels 设为常规面板更好!
  • 如果下载按钮在用户控件中,而UpdatePanel在其父页面中,那么这个解决方案肯定是合适的,因为注册可以在用户控件的page_load事件中完成。
【解决方案3】:

您仍然可以从更新面板中触发下载文档。

我有一个更新面板,里面有 3 个嵌套中继器。在最内部的中继器中,我使用 LinkBut​​tons 构建了一系列下载链接,每个链接都包含一个命令,用于通过 web 服务获取文档并分派它。

每个转发器都有一个 OnItemDataBound 方法。在最后一个中继器中,我有以下

        protected void LinkDocRepeaterOnItemDataBound(object sender, RepeaterItemEventArgs e) {
            if(!(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)) {
            return;
                }
            LinkButton linkButton = (LinkButton)e.Item.FindControlRecursive("LinkId");
            var scriptManager = ScriptManager.GetCurrent(this.Page);
            if (scriptManager != null) {
               scriptManager.RegisterPostBackControl(linkButton);
            }
        }

现在每个链接按钮都会下载一个文档。

【讨论】:

    【解决方案4】:

    我的情况:

    我有一个从 sql 数据加载的长时间运行的 excel 文件,我希望更新进度面板在创建文件时显示微调器 gif,然后从更新面板中下载文件。这比我想象的要复杂。

    这个链接在搜索中的排名很高,在试图避免它之后,结果发现 iframe 对我很有用。

    iframe async download

    这是最终的工作..(这个确切的代码尚未经过测试)

    MyPage.aspx...(在更新面板内,无触发器)

    <asp:Button runat="server" ID="btnExcelExport" Text="Export to Excel" OnClick="btnExcelExport_Click" />
    
    <iframe runat="server" id="ifmExcel" width="0" height="0" marginheight="0" marginwidth="0"
                        frameborder="0" />
    

    MyPage.aspx.cs

            protected void btnExcelExport_Click(object sender, EventArgs e)
            {
                //long running process here, taking advantage of the update progress panel
                var bytes = GetExcelFile();
                //generate a key to pass to the download page to access the file bytes
                var cacheKey = Guid.NewGuid().ToString("N");//N means no hyphens
                //placing the result in cache for a few seconds so the download page can grab it             
                Context.Cache.Insert(key: cacheKey, value: bytes, dependencies: null, absoluteExpiration: DateTime.Now.AddSeconds(30), slidingExpiration: System.Web.Caching.Cache.NoSlidingExpiration);
                ifmExcel.Attributes.Add("src", String.Format("MyDownloadPage.aspx?cacheKey={0}", cacheKey));
            }
    

    MyDownloadPage.aspx.cs...

            protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                var bytes = Context.Cache.Get(Request.QueryString.Get("cacheKey")) as byte[];
                Response.Clear();
                Response.AddHeader(
                    "content-disposition", string.Format("attachment; filename={0}.xlsx", "Invoice"));
                Response.ContentType = "application/xlsx";
                Response.BinaryWrite(bytes);
                Response.End();
            }
        }
    

    它似乎像任何其他异步回发一样按预期工作。

    【讨论】:

      【解决方案5】:

      ASPX 标记:

       <asp:UpdatePanel ID="UpdatePanel5" runat="server" UpdateMode="Conditional">
          <ContentTemplate>
              <asp:GridView ID="gv_Files" runat="server" AllowPaging="True" PageSize="7" OnPageIndexChanging="gv_Files_PageIndexChanging" AutoGenerateColumns="false" EmptyDataText="No files uploaded" GridLines="None">
                  <Columns>
                      <asp:BoundField DataField="Filename" HeaderText="File Name"  ItemStyle-CssClass="Files_css"  />
                      <asp:BoundField DataField="DateCreated" HeaderText="Upload Date" ItemStyle-CssClass="Files_css"  />
                      <asp:TemplateField>
                          <ItemTemplate>
                              <asp:LinkButton ID="lnkDownload" Text="Download" CausesValidation="false" CommandArgument='<%# Eval("FileName_Guid")+  ";" + Eval("Filename")  %>' runat="server" OnClick="DownloadFile"></asp:LinkButton>
                          </ItemTemplate>
                      </asp:TemplateField>
                      <asp:TemplateField>
                          <ItemTemplate>
                              <asp:LinkButton ID="lnkDelete" Text="Del" CausesValidation="false" CommandArgument='<%# Eval("FileName_Guid")+ ";" + Eval("File_ID")+ ";" + Eval("Filename") + ";" + Eval("Platform_Config_ID") %>' runat="server" OnClick="DeleteFile" />
                          </ItemTemplate>
                      </asp:TemplateField>
                  </Columns>
              </asp:GridView>
          </ContentTemplate>
          <Triggers>
              <%--<asp:AsyncPostBackTrigger ControlID="gv_Files" />--%>                   
          </Triggers>
      </asp:UpdatePanel>
      

      后面的代码:

          protected void UploadFile(object sender, EventArgs e)
          {
              if (FileUpload1.HasFile)
              {
                  string FileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
                  string extension = "." + FileName.Split('.')[1].ToString();
                  string FileName_Guid = Convert.ToString(Guid.NewGuid()) + extension;
                  FileUpload1.PostedFile.SaveAs(@"C:\Uploads\" + FileName_Guid);
                  string Platform_Config_ID = PlatformConfigID.Value;
                  DataTable dt = new DataTable();
                  dt = DAL.Upload_File(FileName_Guid, FileName, Platform_Config_ID);
      
                  gv_Files.DataSource = dt;
                  gv_Files.DataBind();
                  ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
                  scriptManager.RegisterPostBackControl(gv_Files);
              }
          }
      
          protected void DownloadFile(object sender, EventArgs e)
          {
              try
              {                
                  LinkButton lnkDownload = (LinkButton)sender;
                  GridViewRow row = (GridViewRow)lnkDownload.NamingContainer;
                  LinkButton download = row.FindControl("lnkDownload") as LinkButton;
                  ScriptManager.GetCurrent(this).RegisterPostBackControl(download);
                  string FileName = (sender as LinkButton).CommandArgument.Split(';')[0].ToString();
                  string OriginalFileName = (sender as LinkButton).CommandArgument.Split(';')[1].ToString();
                  string FilePath = @"C:\Uploads\" + FileName.ToString();
                  FileInfo file = new FileInfo(FilePath);
                  if (file.Exists)
                  {                    
                      Response.ContentType = ContentType;
                      Response.AppendHeader("Content-Disposition", "attachment; filename=" + OriginalFileName);
                      Response.Headers.Set("Cache-Control", "private, max-age=0");
                      Response.WriteFile(FilePath);                    
                      Response.End();                                     
                  }                
              }
              catch (Exception ex)
              {
                  // do nothing
              }
          }
      
      
          protected void DeleteFile(object sender, EventArgs e)
          {
              string FileName_Guid = (sender as LinkButton).CommandArgument.Split(';')[0].ToString();
              string File_ID = (sender as LinkButton).CommandArgument.Split(';')[1].ToString();
              string Filename = (sender as LinkButton).CommandArgument.Split(';')[2].ToString();
              string Platform_Config_ID = (sender as LinkButton).CommandArgument.Split(';')[3].ToString();
              string FilePath = @"C:\Uploads\" + FileName_Guid;
              File.Delete(FilePath);
      
              DataTable dt = new DataTable();
              dt = DAL.Delete_File(File_ID, Filename, Platform_Config_ID);
      
              gv_Files.DataSource = dt;
              gv_Files.DataBind();
          }
      

      【讨论】:

      • 第 1 步:
      • 确保更新面板模式设置如下:UpdateMode="Conditional",然后按照我上面在后面的代码中显示的步骤进行操作。您必须在代码隐藏中将控件注册为回发控件。它就像一个魅力!
      【解决方案6】:

      您不能在更新面板中使用 Response 对象。

      【讨论】:

      • 这就是我的问题。 Response.WriteFile() 正在生成错误。有什么解决办法吗?
      【解决方案7】:

      请尝试以下步骤:

      1.  

        <asp:UpdatePanel ID="UpdatePanel5" runat="server" l**UpdateMode="Conditional"**>
        <asp:GridView ID="gv_Files" runat="server" AllowPaging="True" PageSize="7" OnPageIndexChanging="gv_Files_PageIndexChanging" AutoGenerateColumns="false" EmptyDataText="No files uploaded" GridLines="None">
        
      2. (代码隐藏)UploadFile()

        ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
        scriptManager.RegisterPostBackControl(gv_Files);
        
      3. DownloadFile()

        DownloadFile() --> LinkButton download = row.FindControl("lnkDownload") as LinkButton;
        ScriptManager.GetCurrent(this).RegisterPostBackControl(download);
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-09
        • 2020-07-30
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        • 2013-12-01
        • 1970-01-01
        相关资源
        最近更新 更多