下载功能在 asp.net 的更新面板中不起作用
Posted
技术标签:
【中文标题】下载功能在 asp.net 的更新面板中不起作用【英文标题】:Download feature not working within update panel in 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?要启动整页回发,请将回发触发器添加到更新面板:
<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 个嵌套中继器。在最内部的中继器中,我使用 LinkButtons 构建了一系列下载链接,每个链接都包含一个命令,用于通过 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" margin margin
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 步:您不能在更新面板中使用 Response 对象。
【讨论】:
这就是我的问题。 Response.WriteFile() 正在生成错误。有什么解决办法吗?【参考方案7】:请尝试以下步骤:
<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">
(代码隐藏)UploadFile()
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
scriptManager.RegisterPostBackControl(gv_Files);
DownloadFile()
DownloadFile() --> LinkButton download = row.FindControl("lnkDownload") as LinkButton;
ScriptManager.GetCurrent(this).RegisterPostBackControl(download);
【讨论】:
以上是关于下载功能在 asp.net 的更新面板中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Javascript 警报在 asp.net 的更新面板中不起作用
回发后,我的 JavaScript 函数在 ASP.NET 中不起作用