No more post back after file download in sharepoint
Solution 1
SharePoint registers a JavaScript "on submit" handler. In this handler the global variable _spFormOnSubmitCalled
is set to true
. SharePoint uses this variable to check if a submit was executed and prevents any further submits. Since your "download postback" does not refresh the page this variable remains true
. With the effect that that all other buttons stop working.
As a workaround you can set this variable to false in a client click handler on your download button:
Button btn = new Button();
btn.Text = "Download";
btn.Click += DownloadButton_Click;
// set the client click handler
btn.OnClientClick = "window.setTimeout(function() { _spFormOnSubmitCalled = false; }, 10);"
Of course thats a little hacky and is not garantueed to work in upcoming SharePoint versions.
Solution 2
There is an easy way to work around this. Register OnClientClick event for the button click and set _spFormOnSubmitCalled to false.
<asp:Button ID="Button1" runat="server" Text="Export" onclick="Button1_Click" OnClientClick="javascript:setFormSubmitToFalse()" />
And put the script below in the page/js file.
<script type="text/javascript">
function setFormSubmitToFalse() {
_spFormOnSubmitCalled = false;
return true;
}
</script>
Solution 3
I had no success using '_spFormOnSubmitCalled'. I did have success by placing this in my Page_Load function.
string js = @"_spSuppressFormOnSubmitWrapper = true;";
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "js", js, true);
Ajax second postback not working in Sharepoint in UpdatePanel Provides some background information as to why this is needed.
Solution 4
I am using SharePoint 2010 and DexExpress and inside my visual webpart all I needed to add was the clientSideEvents portion. below is my code...
<dx:ASPxButton
runat="server"
ID="btnExportGrid"
Text="Export Data"
AutoPostBack="False"
OnClick="btnExportGrid_Click" Theme="Office2010Blue" Width="140px"
CausesValidation="False" >
<ClientSideEvents Click="function(s, e) {_spFormOnSubmitCalled=false;_spSuppressFormOnSubmitWrapper=true; }" />
</dx:ASPxButton>
and my C# code
protected void btnExportGrid_Click(object sender, EventArgs e)
{
gridExporter.WriteXlsToResponse();
}
Hope this helps.
Solution 5
there's an even easier solution to all of this. Instead of a download button simply use an
<a>
I usually use something like:
<a href='<%# String.Format("{0}",BuildUrl(Eval("Title")))%>' title='<%#Eval("Title") %>'>Download</a>
Comments
-
kevin almost 2 years
I tried to download a file from sharepoint. But after I download this file, I can't click on other buttons. What is wrong with my coding?
This is my first way.
Response.AppendHeader("content-disposition", "attachment; filename= " + fileName); Response.ContentType = "text/plain"; Response.WriteFile(Server.MapPath("~/" + fileName)); Response.End();
This is my second way
byte[] bytes = System.IO.File.ReadAllBytes("D:\\" + fileName); Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("Content-Type", "application/octet-stream"); Response.AddHeader("Content-Length", bytes.Length.ToString()); Response.AddHeader("content-disposition", "attachment; filename= " + fileName); Response.BinaryWrite(bytes); Response.Flush(); Response.End();
I even comment Response.End() but still the same result.
Is there any other way I should tried?
Any help would be really appreciated. In fact, I posted this question a few days ago, but only one gave me my second way to try but it is still not working.
Thanks.
UPDATE
Here is my GridView under GridView.
<asp:GridView ID="gvGiro" Width="100%" runat="server" GridLines="Both" AllowPaging="false" CssClass="form-table" ShowHeader="false" AllowSorting="false" AutoGenerateColumns="false" OnRowDataBound="gvGiro_RowDataBound"> <Columns> <asp:TemplateField ItemStyle-Width="20%" ItemStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:Label ID="lblValueDate" Text='<%# getDate(Eval("ValueDate")) %>' runat="server" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <ItemTemplate> <asp:GridView ID="gvDetail" runat="server" AllowPaging="false" AllowSorting="false" CssClass="list-table border" HeaderStyle-CssClass="header" AutoGenerateColumns="false"> <Columns> <asp:TemplateField HeaderText="Sequence Number" ItemStyle-HorizontalAlign="Left" ItemStyle-Width="30%" > <ItemTemplate> <%#((DataRowView)Container.DataItem)["MessageSeqNbr"] %> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Total Number of Debit Transaction" ItemStyle-HorizontalAlign="Left" HeaderStyle-HorizontalAlign="Center"> <ItemTemplate> <%#((DataRowView)Container.DataItem)["TotalDebitNbr"] %> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Status" ItemStyle-HorizontalAlign="Left" ItemStyle-Width="25%" HeaderStyle-HorizontalAlign="Center"> <ItemTemplate> <%#((DataRowView)Container.DataItem)["CodeDesc"] %> <asp:HiddenField ID="hidCode" runat="server" Value='<%#((DataRowView)Container.DataItem)["Code"] %>' /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Action" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="10%" HeaderStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:Button ID="btnDownload" runat="server" CssClass="button submit" Text="Download" CommandName="download" OnCommand="onCmd" CommandArgument='<%#Eval("Id") %>' Width="80px"/> <asp:Button ID="btnUnbatch" runat="server" CssClass="button generic" Text="Un-Batch" CommandName="unbatch" OnCommand="onCmd" CommandArgument='<%#Eval("Id") %>' Width="80px"/> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
Here is my cs file
protected void gvGiro_RowDataBound(object sender, GridViewRowEventArgs e) { GridView gr; if (e.Row.RowType == DataControlRowType.DataRow) { gr = (GridView) e.Row.FindControl("gvDetail"); using (class2 ct2= new Class2()) { Label lblValueDate = (Label)e.Row.FindControl("lblValueDate"); DateTime dt= DateTime.MinValue; DataSet ds= ct2.GetData(dt); gr.DataSource = ds; gr.DataBind(); } } } protected void onCmd(object sender, CommandEventArgs e) { string id; switch (e.CommandName) { case "unbatch": id= e.CommandArgument.ToString(); Unbatch(id); break; case"download": id= e.CommandArgument.ToString(); Download(id); break; default: break; } } protected void Download(string id) { // to do - substitute all hard-code guid Guid batchId = new Guid(id); string fileName = ""; Class1 ct = new Class1(); { if (!ct.FileExists(batchId , ref fileName)) { byte[] bytes = System.IO.File.ReadAllBytes("D:\\" + fileName); Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("Content-Type", "application/octet-stream"); Response.AddHeader("Content-Length", bytes.Length.ToString()); Response.AddHeader("content-disposition", "attachment; filename= " + fileName); Response.BinaryWrite(bytes); Response.Flush(); Response.End(); }
-
kevin over 12 yearsI am trying to use your way. But unfortunately, I use onCommand for this button and those buttons are inside a GridView. When I try to substitue btn.Click+=DownloadButton_Click with btn.Command = onCmd, it does not work.
-
Stefan over 12 yearscan you post the code which creates the button or the grid view?
-
kevin over 12 yearsThx for ur help, in fact, it's GridView inside GridView. I will update in my question.
-
Stefan over 12 yearsAdding the
OnClientClick
handler in the asp does not work? =><asp:Button ... CommandName="download" OnCommand="onCmd" CommandArgument='<%#Eval("Id") %>' OnClientClick="window.setTimeout(function() { _spFormOnSubmitCalled = false; }, 10);" ... />
-
kevin over 12 yearsit works perfectly now !!! Thx a lot !!! You are awesome, it took about 4 hours from me before u help me!!
-
kevin over 12 years-> hi again !! One question, after downloading, I would like to disable the download button on the gridview. So I call gv.DataBind(). It does not work. What can the my problem? I even comment Response.End(). Same result.
-
kevin over 12 yearsIn BuildUrl , I should write the download coding ?
-
Tjassens over 12 yearsyep, thats exactly what you should do. I usually make a reference to a utility class where I do this but you can also do it in the code behind of your user control.
-
Etienne over 10 yearsthis worked for me while changing the _spFormOnSubmitCalled didn't so +1 and thanks for saving my day
-
Wint about 10 yearsYou saved my day buddy! (I just added this code to my aspx page and it worked like a charm: _spSuppressFormOnSubmitWrapper = true)
-
SP Developer almost 8 yearsThanks flip.. tried lots of tricks but only yours work for me :-)...thanks again