Download feature not working within update panel in asp.net
To initiate a full page postback, you add a postback trigger to your update panel:
<asp:UpdatePanel runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="YourControlID" />
</Triggers>
<ContentTemplate>
.....
You cannot return an attachment in an UpdatePanel partial postback, since the results are used by the ScriptManager to update a DIV (not the whole response). The simplest fix for what you're trying to do would be to make your download button as a postback control. That would cause that button to initiate a full postback. Here's the code below to include in your Page_Load
ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(this.lnkDownload);
You can still trigger download doc from inside an Update Panel.
I have an update panel and inside I have 3 nested repeaters. In the most inner repeater I build a series of download links using LinkButtons, each one containing a command to fetch the document via webservice and dispatching it.
Each repeater has an OnItemDataBound method. In the last repeater I have the following
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);
}
}
Each Linkbutton now downloads a document.
My situation:
I had a long running excel file loaded from sql data and I wanted update progress panel to display the spinner gif while the file was created and then download the file from within the update panel. It was trickier than I thought.
This link came up high on searches and after trying to avoid it, it turned out that an iframe was useful to me.
iframe async download
Here is what ended up working.. (this exact code has not been tested)
MyPage.aspx...(inside update panel, no triggers)
<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();
}
}
It seems to work as expected like any other async post back would.