Hello!
After downloading a file from a grid, my page keeps loading in loop, never stoppin. In order to be abble to do the download,
Along the way, i found out that the following function to disable AJAX was necessary to allow postback, so i believe the issue comes from here.
function onRequestStart(sender, args) {
try {
if (args.get_eventTarget().indexOf("lnkDownload") >= 0) {
args.set_enableAjax(false);
return true;
}
}
catch (ex) {
alert("Error pushing postback: " + ex.message);
}
}
I also tried a similar function,, seting timeout in order to try to reestablish the normal behavour of the page, with any success.
function gridCommand(sender, args) {
if (args.get_commandName() == "download_file") { // "DownloadAttachment"
manager.set_enableAJAX(false);
setTimeout(function () {
manager.set_enableAJAX(true);
}, 0);
}
}
Any ideas on the solution for this problem?
Hi Rúben,
It all depends on how you have configured the Grid. I have tested and the example from the Export from Ajaxified Grid is working as expected. In your case, perhaps the Grid has a different structure than we show in the example.
Show us how you have enabled AJAX for the Grid, how is the Grid configured and also, show which button initiates the export and how.
Hello Attila.
I have set EnableAJAX="true". I am not exporting grid content, but external server stored files, there are displayed in the grid.
The download is made, and after complete, AJAX loading panel keeps loading until a page reload is done.
This is my download button config, and respective method, being "ID" the DB row containing the stored file. "FileContent" represents the binary content stored
<telerik:GridTemplateColumn UniqueName="Download" HeaderText="Ficheiro">
<ItemTemplate>
<asp:LinkButton runat="server"
ID="lnkDownload" Text="Download" CommandName="download_file" OnClientClick="gridCommandD" CommandArgument='<%# Eval("ID") %>' OnClick="link1_Click">
</asp:LinkButton>
</ItemTemplate>
</telerik:GridTemplateColumn>
protected void link1_Click(object sender, EventArgs e) //download tabela { var ID = Convert.ToInt32(((LinkButton)sender).CommandArgument); var model = listagembll.GetFileByID(ID); if (model.FileContent != null) { Response.Clear(); //Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("Content-Type", "Application/octet-stream"); Response.AddHeader("Content-Length", model.FileContent.Length.ToString()); Response.AddHeader("Content-Disposition", "attachment; filename=" + model.Ficheiro + "." + model.FileTipo); //attachment "attachment;filename=Excel_Export.xlsx Response.BinaryWrite(model.FileContent); Response.Flush(); Response.End(); }
AJAX related, i have the following:
function gridCommand(sender, args) { if (args.get_commandName() == "download_file") { // "DownloadAttachment" manager.set_enableAJAX(false); setTimeout(function () { manager.set_enableAJAX(true); }, unction0); } } <telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel2" runat="server" Width="256px" Height="64px" > </telerik:RadAjaxLoadingPanel> <telerik:RadAjaxManagerProxy ID="RadAjaxManager1" runat="server"> </telerik:RadAjaxManagerProxy>
Something doesn't add up. I can't put the code together.
By looking at the LinkButton, that raises a few questions as I do not see what is happening behind the scene:
<asp:LinkButton runat="server" ID="lnkDownload" Text="Download" CommandName="download_file" OnClientClick="gridCommandD" CommandArgument='<%# Eval("ID") %>' OnClick="link1_Click">
So my questions are:
This is why I asked for the "Complete" implementation. There I can see and understand what is happening.
I see that you're using a RadAjaxManagerProxy which tells me that MasterPage and ContentPages are involved, correct? If so, where did you place the RadAjaxManager, where is the RadAjaxManagerProxy, where is the Grid, and how did you associate the Grid's ID with the RadAjaxManager or RadAjaxManagerProxy?
You can see in the Quick Example section how to enable AJAX for controls. The EnableAJAX="true" will only turn the RadAjaxManager On or Off. It does not enable AJAX for any controls on the page.
Please review the following articles to get a better idea of why I am asking all these questions:
I am very sorry for not explaining myself the best way..
gridCommandD is a typo, i use the "gridCommand" JS function, which allows the download to be made by disabling AJAX after button click, otherwise AJA.X blocks the "responses" usage. the expected here, was that with timeout, the page instatly return normal behaviour, which doesn't happen
function gridCommand(sender, args) { if (args.get_commandName() == "download_file") { // "DownloadAttachment" manager.set_enableAJAX(false); setTimeout(function () { manager.set_enableAJAX(true); }, 0); } }
I am using a usercontrol page, so the use of RadAjaxManagerProxy. and i don't have access to master page, being part of a larger environment, out of my scope, but this approach implemented is implemented in other user controls sucssefully,. After your advice and some search, i associated the grid with ajax manager, adding the "ajax settings". however, it made no difference in the behaviour.
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel2" runat="server" Width="256px" Height="64px" > </telerik:RadAjaxLoadingPanel> <telerik:RadAjaxManagerProxy ID="RadAjaxManager1" runat="server"> <AjaxSettings> <telerik:AjaxSetting AjaxControlID="gvTimesheets"> <UpdatedControls> <telerik:AjaxUpdatedControl ControlID="gvTimesheets" /> <telerik:AjaxUpdatedControl ControlID="RadWindowManager2" /> <telerik:AjaxUpdatedControl ControlID="RadInputManager1" /> </UpdatedControls> </telerik:AjaxSetting> </AjaxSettings> </telerik:RadAjaxManagerProxy>
In the ACSX.CS, i associate the function in the item command "download_file", having tried several approaches, or just leaving the call empty, always with any results. The Link1_click method is supposed to get the binary file from server. converted it, and present it in the user machine, which is working, because the download is done.
In the ACSX page, i have the grid and button
<telerik:RadGrid ID="gvTimesheets" OnItemDataBound="gvTimesheets_ItemDataBound" OnDeleteCommand="gvTimesheets_DeleteCommand" OnInsertCommand="gvTimesheets_InsertCommand" OnUpdateCommand="gvTimesheets_UpdateCommand" OnNeedDataSource="gvTimesheets_NeedDataSource" OnItemCommand="gvTimesheets_ItemCommand" EnableAJAX="true" GridLines="Horizontal" runat="server" AllowAutomaticDeletes="True" AutoGenerateInsertColumn="true" AllowAutomaticUpdates="True" AllowAutomaticInserts="True" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellSpacing="0" EnableViewState="False" RenderMode="Lightweight" Width="98%" OnItemDeleted="gvTimesheets_ItemDeleted" OnItemInserted="gvTimesheets_ItemInserted" OnItemUpdated="gvTimesheets_ItemUpdated" OnItenCreated="gvTimesheets_ItemCreated" > <PagerStyle AlwaysVisible="false" FirstPageToolTip="Início" LastPageToolTip="Fim" NextPageToolTip="Seguinte" PageSizeLabelText="Registos por Página" PrevPageToolTip="Anterior" PagerTextFormat="Change page: {4}   Total de registos: <strong>{5}</strong> total de páginas: <strong> {1}</strong>" Mode="NumericPages" Position="Bottom" PageSizeControlType="RadComboBox" /> <MasterTableView DataKeyNames="ID" InsertItemPageIndexAction="ShowItemOnLastPage" CommandItemSettings-ShowRefreshButton="true" AllowMultiColumnSorting="false" GridLines="None" NoMasterRecordsText="Sem registos" CommandItemDisplay="Top" AutoGenerateColumns="false" InsertItemDisplay="Top"> <CommandItemTemplate> <telerik:RadButton CommandName="Rebind" RenderMode="Lightweight" ID="Rebindbutton" Text="Atualizar lista" ToolTip="Atualizar a lista" runat="server" style="background:none; border:none; color:darkblue;" > <Icon PrimaryIconCssClass=" rbRefresh"></Icon> </telerik:RadButton> </CommandItemTemplate> <Columns> <telerik:GridBoundColumn DataField="ID" DataType="System.Int32" HeaderText="ID Ts." ReadOnly="True" SortExpression="ID" UniqueName="ID"> <HeaderStyle Width="5%" /> <ColumnValidationSettings> <ModelErrorMessage Text="" /> </ColumnValidationSettings> </telerik:GridBoundColumn> <telerik:GridBoundColumn DataField="RecursoHumano.ID" DataType="System.Int32" ReadOnly="True" FilterControlAltText="Filter column" Visible="false" HeaderText="Investigador" UniqueName="IDRecursoHumano" > <ColumnValidationSettings> <ModelErrorMessage Text="" /> </ColumnValidationSettings> </telerik:GridBoundColumn> <telerik:GridBoundColumn DataField="Ficheiro" FilterControlAltText="Filter por ficheiro" HeaderText="NomeFicheiro" UniqueName="Ficheiro"> <HeaderStyle Width="10%" /> <ColumnValidationSettings> <ModelErrorMessage Text="" /> </ColumnValidationSettings> </telerik:GridBoundColumn> <telerik:GridBoundColumn DataField="FileTipo" FilterControlAltText="Filter por tipo de ficheiro" HeaderText="Formato" UniqueName="FileTipo" Visible="true"> <HeaderStyle Width="5%" /> <ColumnValidationSettings> <ModelErrorMessage Text="" /> </ColumnValidationSettings> </telerik:GridBoundColumn> <telerik:GridBoundColumn DataField="FileContent" FilterControlAltText="Filter por conteudo de ficheiro" HeaderText="Ficheiro" UniqueName="FileContent" Visible="false"> <ColumnValidationSettings> <ModelErrorMessage Text="" /> </ColumnValidationSettings> </telerik:GridBoundColumn> <telerik:GridTemplateColumn UniqueName="Download" HeaderText="Ficheiro"> <ItemTemplate> <asp:LinkButton runat="server" ID="lnkDownload" Text="Download" CommandName="download_file" OnClientClick="gridCommandD" CommandArgument='<%# Eval("ID") %>' OnClick="link1_Click"> </asp:LinkButton> </ItemTemplate> </telerik:GridTemplateColumn> </Columns> <CommandItemTemplate> </CommandItemTemplate> <CommandItemStyle HorizontalAlign="Right" /> </MasterTableView> <ClientSettings > </ClientSettings> </telerik:RadGrid>
Thank you for sharing the details. It all makes sense now.
Here are my suggestions:
The first and most important is to make sure, that this WebUserControl (ASCX) is not located inside a Container that is already Ajaxified. See Understanding AJAX Controls. You will need to consult with the team responsible to confirm this with you. If this UserControl is already Ajaxified in the ASPX or MasterPage, do not enable AJAX additionally on the UserControl. Once you're sure that AJAX controls are not Nested meaning that no Control is Ajaxified inside another AJAX enabled control.
Once done, you can try one of the different approaches listed in the Exclude Controls from Ajaxifying article. For example this one: Cancel the AJAX Request on InitializeRequest Event
In order to complete the scenario, It is important that you understand the difference between the OnCommand event of the Grid and the ClientClick event of the LinkButton. They are not the same, and so you will need to be careful what properties are you trying to access in the event arguments.
Here is my suggestion:
Use the following LinkButton in the Template Column
<telerik:GridTemplateColumn UniqueName="Download" HeaderText="Ficheiro"> <ItemTemplate> <asp:LinkButton runat="server" ID="lnkDownload" Text="Download" CommandName="download_file" CommandArgument='<%# Eval("ID") %>'></asp:LinkButton> </ItemTemplate> </telerik:GridTemplateColumn>
Implement the approach from the article. Do not change anything except the "button's ID" inside the IndexOf() function.
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server"> <script> Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initRequest); function initRequest(sender, args) { if (args.get_postBackElement().id.indexOf("lnkDownload") != -1) { args.set_cancel(true); //stop async request sender._form["**EVENTTARGET"] = args.get_postBackElement().id.replace(/\_/g, "$"); sender._form["**EVENTARGUMENT"] = ""; sender._form.submit(); return; } } </script> </telerik:RadScriptBlock>
In the ItemCommand event of the Grid do this:
protected void RadGrid1_ItemCommand(object sender, GridCommandEventArgs e) { if(e.CommandName == "download_file") { var ID = e.CommandArgument; var model = listagembll.GetFileByID(ID); if (model.FileContent != null) { Response.Clear(); //Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("Content-Type", "Application/octet-stream"); Response.AddHeader("Content-Length", model.FileContent.Length.ToString()); Response.AddHeader("Content-Disposition", "attachment; filename=" + model.Ficheiro + "." + model.FileTipo); //attachment "attachment;filename=Excel_Export.xlsx Response.BinaryWrite(model.FileContent); Response.Flush(); Response.End(); } } }
Please check the articles I shared for more information. They contain all the details that you will need to understand what is happening in such scenarios.
Hello Atilla
I tried the suggested implementation, but nothing happens when i try to download the file. When debugging, the event isn't triggered when the button is clicked.
You think the issue could be in master page?
Hi Ruben, share a runnable sample that produces the error and I will check it for you. You can use the sample I shared with you in the other Forum thread: Problem using child user control.
Modify this replicate the issue and send it back to me.
I don't know if you'll be able to run this sample because i don't have all the configs.. Anyways, you can check my full logic. If you could not find the issue, i am sorry for the bother.
I don't know if it is right to mention that in this thread, but about the forum thread https://www.telerik.com/forums/problem-using-child-user-control, i was also not able to resolve the problem, having paused it for a few days to focus on this issue.. But if you could check that as well, since i am sending you this sample it would be great help!
I am using https://docs.telerik.com/devtools/aspnet-ajax/controls/grid/data-editing/insert-records/inserting-values-using-usercontrol-formtemplate as a guide, using the ItemCommand event ' to trigger the edit form, but i can´t addapt the DataRow syntax to my architecture, and as well, to my insertFile method (BLL).
Thank you in advance!
Hi Ruben.
I looked at the code and because I am not able to run it, I can't tell where the problem comes from. I see that you're trying to enable AJAX for some controls inside the UserControl which is then loaded by the Grid. I suggest that you enable AJAX for the Grid itself and not worry about the UserControl because all components will have AJAX enabled.
Check out the Understanding AJAX Controls article to learn more about the AJAX Controls and how to use them. You will need to make sure that AJAX is configured correctly and that might resolve the issue.
I could help as well but for that, I would need a runnable sample. Without a sample, we are only making wild guesses and predictions which does not help in the current case.