How to download a pdf from a panel in an update panel - c#

I have a site that uses master pages.
One of my content pages is basically a large UpdatePanel. Inside that UpdatePanel is a regular Panel. Inside the regular Panel is a Gridview. Inside the Gridview is a Linkbutton that points to a pdf stored in my database.
When I click the Linkbutton to retrieve the pdf, nothing happens.
I have this working on another page that has no UpdatePanel.
I have already tried firing an 'external' button from the Linkbutton and registering this button as a PostBack event. The page posts back when I click the Linkbutton but the pdf is not being sent to the user.
Here is some sample code:
<asp:UpdatePanel ID="UpdatePanelClaims" runat="server">
<ContentTemplate>
<asp:Panel ID="upClaimAttachment" runat="server" Visible="false" >
<table id="gridClaimAttachmentTable" runat="server" class="table" >
<tr>
<td >
<asp:GridView ID="grdClaimAttachment" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" CssClass="table table-striped table-bordered table-condensed table-hover" EmptyDataText="No Attachments for this Claim."
EnableTheming="False" onpageindexchanging="grdClaimAttachment_PageIndexChanging" PageSize="15" OnRowCommand="grdClaimAttachment_RowCommand"
OnRowDataBound="grdClaimAttachment_RowDataBound" >
<PagerStyle CssClass="bs-pagination" />
<AlternatingRowStyle CssClass="alternateColor" />
<RowStyle CssClass="rowsStyle" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-CssClass="hideColumn" HeaderStyle-CssClass="hideColumn" >
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:TemplateField HeaderText="File Name">
<ItemTemplate>
<asp:LinkButton ID="btnViewAttachment" Text='<%#Eval("FileName") %>' CommandName="ViewAttachment"
CommandArgument="<%# Container.DataItemIndex %>" runat="server"></asp:LinkButton></ItemTemplate>
</asp:TemplateField>
<asp:ButtonField ButtonType="Button" CommandName="btnDelete" Text="Delete">
<ControlStyle CssClass="btn btn-info btn-xs " />
</asp:ButtonField>
</Columns>
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#E9E7E2" />
<SortedAscendingHeaderStyle BackColor="#506C8C" />
<SortedDescendingCellStyle BackColor="#FFFDF8" />
<SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
</td>
</tr>
<tr >
<td>
<div class="container">
<div class="form-group form-group-sm form-groupNoSpace">
<div class="row">
<div class=" col-xs-4 col-xs-offset-4 text-right">
<asp:Button ID="btnClaimAttachmentAdd" runat="server" CssClass="btn btn-primary btn-sm btn-block" Text="Add Attachment" OnClick="btnClaimAttachmentAdd_Click"/>
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
</asp:Panel> <%-- Attachment Update Panel --%>
<asp:Button ID="btnClickMe" runat="server" OnClick="btnClickMe_Click" Visible="false" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnClickMe" />
</Triggers>
</asp:UpdatePanel> <%-- UpdatePanelClaims --%>
In the code behind I have this:
protected void btnClickMe_Click(object sender, EventArgs e, ClaimAttachment objAttachment)
{
ViewAttachment(objAttachment);
}
private void ViewAttachment(ClaimAttachment objAttachment)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AppendHeader("content-disposition", "attachment;filename=" + objAttachment.FileName);
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(objAttachment.Attachment);
Response.Flush();
Response.End();
}
UPDATE: Forgot some critical code!
protected void grdClaimAttachment_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
int index = Convert.ToInt32(e.CommandArgument);
if (index >= grdClaimAttachment.Rows.Count)
return;
int IDkey = Convert.ToInt32(grdClaimAttachment.Rows[index].Cells[0].Text);
ClaimAttachment objClaimAttachment = ClaimAttachment.RetrieveById((string)Session["Username"], IDkey);
if (e.CommandName == "btnDelete")
{
ltlDeleteID.Text = IDkey.ToString();
ltlRecordType.Text = "attachment";
confirmDialog(string.Format("DELETE Attachment: {0} ?", objClaimAttachment.FileName));
}
else if (e.CommandName == "ViewAttachment")
{
//btnClickMe.CommandArgument = IDkey.ToString();
//btnClickMe_Click(sender, e);
btnClickMe.Click += new EventHandler((s1, e1) => btnClickMe_Click(s1, e1, objClaimAttachment));
btnClickMe_Click(sender, e, objClaimAttachment);
}
}
catch (BLException be)
{
errDialog(be.Message);
}
}
The Linkbutton in the grid is actually calling the Click event of an external button to perform the pdf download...
What am I missing?? Like I said, this works if I remove all UpdatePanels but I need them for other things...
thx!

The PostBackTrigger class is key to your solution, as it can be used to trigger the full page reload required for the download reponse to work. Downloads simply will not work from a partial postback.
However, as the buttons that should trigger the postback are inside your grid, using a single PostBackTrigger in the page markup is not enough, you need a specific trigger for each button / row.
Use something like this (call it from your Page_Load)
private void RegisterPostBackControls()
{
foreach (GridViewRow row in grdClaimAttachment.Rows)
{
LinkButton button = row.FindControl("btnViewAttachment") as LinkButton;
ScriptManager.GetCurrent(this).RegisterPostBackControl(button);
}
}

Related

Accessing grid view row data C#

I am trying to set the value of a textbox to the value of a column in a gridview. I am getting the row from a LinkButton.
The first TextBox1.Text line below works correctly to set the value of the textbox to the row number.
The second TextBox1.Text line below does nothing to my textbox. I am expecting the value of the row(index) and column(1), but I get nothing. There is definitely data in the gridview. The gridview is 10+ columns wide, and I have checked the value from 0-5 and get nothing in the textbox.
I am not running it with both lines uncommented out at once.
I am doing all of this to troubleshoot an issue being caused by it.
protected void lnkbtnPassRowData_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)sender;
GridViewRow gvr = (GridViewRow)btn.NamingContainer;
if (gvr != null)
{
int index = Convert.ToInt32(gvr.RowIndex.ToString());
TextBox1.Text = GridStaffMyJobs.Rows[index].RowIndex.ToString();
TextBox1.Text = GridStaffMyJobs.Rows[index].Cells[1].Text;
}
}
Here is the code from the gridview that contains the link button.
<form id="StaffMyJobs" runat="server">
<div>
<h3>My Jobs</h3>
</div>
<div>
<asp:Label ID="lblHired" runat="server" Text="Rows in green indicate jobs that have been filled." Visible="False" BorderColor="#FF0909" Font-Bold="True" Font-Underline="True" ForeColor="YellowGreen"></asp:Label>
<br />
<asp:Label ID="lblOffers" runat="server" Text="Rows in red indicate jobs that have pending offers." Visible="False" BorderColor="#FF0909" Font-Bold="True" Font-Underline="True" ForeColor="Red"></asp:Label>
<br />
<asp:Button ID="btnAddJob" runat="server" Text="Add a Job" OnClick="btnAddJob_Click" Visible="true" />
<br />
<br />
</div>
<div>
<asp:GridView ID="GridMoreJobs" runat="server" AutoGenerateColumns="False" DataSourceID="SQLMoreJobs" >
<Columns>
<asp:BoundField DataField="more_jobs" HeaderText="more_jobs" SortExpression="more_jobs" Visible="false" />
</Columns>
</asp:GridView>
</div>
<div>
<asp:GridView ID="GridStaffMyJobs" runat="server" AutoGenerateColumns ="False" DataSourceID="SQLStaffMyJobs" ShowFooter="True" OnRowDataBound="GridMoreJobs_RowDataBound" HorizontalAlign="Center" >
<Columns>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton ID="lnkbtnPassRowData" Text='Reopen'
runat="server"
OnClick="lnkbtnPassRowData_Click" Visible='<%#
CanReopen((object)Eval("student_hired")) %>' />
</ItemTemplate>
</asp:TemplateField>
</form>
Here is a screenshot of executing the page and letting the line run that puts the index of the row in the textbox.

Pass row index to modal popup window from buttonField in GridView

I have a GridView (see below) which uses ButtonField buttons to launch modal popup windows.
Here is the GridView
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_ButtonClick" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" CssClass="mGrid" AllowPaging="True" PagerStyle-CssClass="pgr"
AlternatingRowStyle-CssClass="alt" OnRowEditing="GridView1_RowEditing" AutoGenerateColumns="False">
<AlternatingRowStyle BackColor="#F7F7F7" CssClass="alt" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
<Columns>
<asp:BoundField HeaderText="BeaconID" ShowHeader="True" Visible="True" DataField="beaconObjectid" />
<asp:BoundField DataField="aliasName" HeaderText="My Beacon Name" />
<asp:ButtonField ButtonType="Button" CommandName="AssignName" Text="Assign Name"/>
<asp:BoundField HeaderText="Action Type" DataField="actionType" />
<asp:BoundField DataField="actionContent" HeaderText="Action Content" />
<asp:ButtonField ButtonType="Button" CommandName="AssignAction" Text="Assign/Change Action"/>
</Columns>
<PagerStyle CssClass="pgr" />
</asp:GridView>
This works fine to open the modal window like this one, using the C# code shown further down:
<asp:Button ID="showModal3" runat="server" Text="Show Modal" CssClass="hiddenButton"/>
<asp:Panel ID="Panel3" runat="server" CssClass="modalPopup">
<div class="header">
Set Alias Name
</div>
<div class="body">
Set a new name for your beacon
<br />
<br />
<div style="float: none;">
<asp:TextBox ID="AliasNameTextBox" runat="server" Height="21px" Width="300px"></asp:TextBox>
</div>
</div><br/>
<div class="footer" align="right">
<asp:Button ID="setAliasOK" runat="server" Text="OK" CssClass="yes" OnClick="setAliasOK_Click" CausesValidation="False" />
<asp:Button ID="setAliasCancel" runat="server" Text="Cancel" CssClass="no" />
</div></asp:Panel>
<ajaxToolkit:ModalPopupExtender ID="SetAliasNameModalPopupExtender" runat="server" CancelControlID="setAliasCancel" DropShadow="True" PopupControlID="Panel3" TargetControlID="showModal3" BackgroundCssClass="modalBackground"></ajaxToolkit:ModalPopupExtender>
In my C# code, i'm getting the index of the buttons like this so i know which row was clicked, which all works well:
protected void GridView1_ButtonClick(object sender, GridViewCommandEventArgs e)
{
GridViewRow row = GridView1.Rows[Convert.ToInt32(e.CommandArgument)]; // this gets the row
string id = row.Cells[0].Text;
string name = row.Cells[1].Text;
string actionText = row.Cells[3].Text;
if (e.CommandName == "AssignName")
{
SetAliasNameModalPopupExtender.Show();
AliasNameTextBox.Text = name;
}
if (e.CommandName == "AssignAction")
{
ChooseActionModalPopupExtender.Show();
}
Label1.Text = name;
Label2.Text = actionText;
Label3.Text = id;
currentlySelectedRow = Convert.ToInt32(e.CommandArgument);
beaconIDnumber = id;
}
The problem is when i click the 'OK' button from my modal popup window. I need to have access to the row index from the gridview buttonfield that called it. My OK button click event looks like this:
protected void setAliasOK_Click(object sender, EventArgs e)
{
var newName = AliasNameTextBox.Text;
ParseChangeAliasName(beaconIDnumber, newName);
SetAliasNameModalPopupExtender.Hide();
}
So ultimately what i'm asking, is how do i pass the gridview row to the modal window so i can use data from the respective row cell - in this case the beacon ID (DataField="beaconObjectid" in the gridview).
I've even tried setting global variables in the GridView1_ButtonClick method, and then referencing them in the setAliasOK_Click method, but they get wiped as soon as the modal window opens.
Ideally i want to do this without using Javascript if possible.
in the same way you get
GridViewRow row = GridView1.Rows[Convert.ToInt32(e.CommandArgument)];
you can set your Button attributes:
setAliasOK.CommandName = "AliasOK" ;
setAliasOK.CommandArgument = e.CommandArgument ;
But you need to process your button's RowCommand event rather than the Click event to get to the Button's Command parameters

Button not firing inside Accordion Panes inside which is inside Update Panel in ASP.NET

I am customizing one website but , while using triggers in update panel the click event is not firing.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="True"
Also see the Content Template
<ContentTemplate>
<table width="100%">
<tr>
<td>
<cc1:accordion id="Accordion1" runat="server" headercssclass="headeraccordian">
<panes>
<cc1:accordionpane ID="AccordionPane1" runat="server">
<header>
<a href="#">
<asp:Label ID="dailyreport" CssClass="lbl" runat="server" Text="Daily Report"></asp:Label></a>
</header>
<content>
<div>
<asp:TextBox ID="txtDate" runat="server" ReadOnly="True" Width="94px"></asp:TextBox>
<asp:Button ID="btnCal" runat="server" Text="Select Date" OnClick="btnCal_Click" />
<asp:Button ID="btnDownLoads" runat="server" Text="Download" OnClick="btnDownLoads_Click" />
<asp:Calendar ID="cal" runat="server" OnSelectionChanged="cal_SelectionChanged" BackColor="White"
BorderColor="White" BorderWidth="1px" Font-Names="Verdana" Font-Size="9pt" ForeColor="Black"
Height="190px" NextPrevFormat="FullMonth" Width="350px">
<SelectedDayStyle BackColor="#333399" ForeColor="White" />
<TodayDayStyle BackColor="#CCCCCC" />
<OtherMonthDayStyle ForeColor="#999999" />
<NextPrevStyle Font-Bold="True" Font-Size="8pt" ForeColor="#333333" VerticalAlign="Bottom" />
<DayHeaderStyle Font-Bold="True" Font-Size="8pt" />
<TitleStyle BackColor="White" BorderColor="Black" BorderWidth="4px" Font-Bold="True"
Font-Size="12pt" ForeColor="#333399" />
</asp:Calendar>
</div>
</content>
</cc1:accordionpane>
</panes>
</cc1:accordion>
</td>
</tr>
</table> </ContentTemplate>
Also see the triggers
Also see the code-behind for the button click:-
protected void btnDownLoads_Click(object sender, EventArgs e)
{
string wdr = "dR";
string value = txtDate.Text;
string str = wdr + value;
string foldername = "Daily";
string filename = str + ".pdf";
var filePath = Path.Combine(#"D:\REPORTS\" + foldername + " ", filename);
if (File.Exists(filePath))
{
Response.ContentType = #"application/pdf";
Response.AddHeader(
#"Content-Disposition",
#"attachment; filename=" + Path.GetFileName(filePath));
Response.WriteFile(filePath);
Response.End();
}
else
{
Response.Write("<script>alert('No report uploaded for this date')</script>");
}
}
I just want click event to be fired on click, and it is .............
but Response.End() function is not working properly while downloading the file.
See the page_load code;-
try
{
this.SmartNavigation = true;
if (this.IsPostBack == false)
{
//FillReport();
txtDate.Text = DateTime.Now.ToString("dd-MM-yyyy");
cal.Visible = false;
currentdate.Text = DateTime.Now.Date.ToLongDateString();
#region edited
#region download click
checkdailydata();
#endregion
#endregion
}
}
catch (Exception ext) // Edited Jimit included try catch
{
CreateLogFiles ls = new CreateLogFiles();
ls.ErrorLog(Server.MapPath(#"~\ErrorLog\ErrorMsg"), ext.Message);
}
I also faced the same issue long time back
Try Removing the Trigger on .aspx page and add(Registered Control) like below code on page_load outside !page.isPostback{})
ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(btnDownLoads);
See whether it works or not

Row Command Event of GridView is not working in ajax tab container

I want to download a file with link button of grid view. but the row command does not firing. the grid view is in Ajax tab container---Update panel.
Its working fine in Normal form without ajax tab container control.
Design Page:
<asp:TabPanel ID="TabPanel2" runat="server" HeaderText="Download" Height="150px" Width="500px">
<HeaderTemplate>
Download
<asp:GridView ID="GridView1" runat="server" onrowcommand="GridView1_RowCommand" AutoGenerateColumns="False"
Height="80%" Width="70%">
<Columns>
<asp:BoundField DataField="id" HeaderText="id" SortExpression="id"/>
<asp:BoundField DataField="filename" HeaderText="filename" SortExpression="filename"/>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Download" CommandArgument='<%#Eval("id")%>' ForeColor="White" CausesValidation="true" >DownLoad</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#FF6699" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</form>
<br />
<br />
<br />
</ContentTemplate>
</asp:TabPanel>
Code Behind:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = ((GridViewRow)((LinkButton)e.CommandArgument).Parent.Parent).RowIndex;
if (e.CommandName=="Download")
{
Tabs.ActiveTabIndex = 1;
int Id = Convert.ToInt32((e.CommandArgument).ToString());
GridViewRow row = GridView1.Rows[Id];
string filename = row.Cells[1].Text;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
Response.TransmitFile(Server.MapPath("~/Docs/" +filename));
Response.End();
}
you need to set Download link as PostbackControl, try below code in RowDataBound
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
LinkButton lb = e.Row.FindControl("LinkButton1") as LinkButton;
if(lb != null)
ScriptManager.RegisterPostbackControl(lb);
}

How to get Button1 Id on button2 click on server side asp.net c#

here is my aspx view
<asp:GridView ID="gvdatasubcategory" runat="server" AllowPaging="false" AllowSorting="false"
CssClass="gvdatarow" ShowHeader="false" AutoGenerateColumns="False" OnRowCommand="gvdatasubcategory_RowCommand">
<Columns>
<asp:TemplateField ItemStyle-Font-Names="Estrangelo Edessa" HeaderStyle-Font-Names="Estrangelo Edessa">
<ItemTemplate>
<div class="subcategory_type">
<div id="abd" runat="server">
<asp:LinkButton ID="button1" runat="server" CssClass="subcategory_name"
Width="80px" Height="26px" Text='<%#DataBinder.Eval(Container.DataItem, "SubCategory")%>'
CommandName="Test"></asp:LinkButton>
</div>
</div>
</ItemTemplate>
<HeaderStyle Font-Names="Estrangelo Edessa" Width="5px" />
<ItemStyle Font-Names="Estrangelo Edessa" Width="5px" Wrap="false" HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="button2 " runat="server" CssClass="category_name" Text="getid"
OnClick="button2 _Click" />
these buttons are in gridview and i need to get the first button id on second button click in code behind
Thank you in advance
Raveendra
If you are looking for Linkbutton object, thenyou can use FindControl method as:
LinkButton button1 = (LinkButton)gvdatasubcategory.Rows[0].Cells[0].FindControl("button1");
string buttonid = button1.ClientID; //gives client side id of the Linkbutton
But keep in mind that grid should contain th rows, otherwise you will get null. If you need all Linkbutton instances, then you can loop through the datarows to get each linkbutton ids.
You can try this code below:
protected void button2_Click(object sender, EventArgs e)
{
foreach(GridViewRow row in gvdatasubcategory.Rows)
{
LinkButton btn = (LinkButton)row.FindControl("button1");
string strClientID = string.Empty;
strClientID = btn.ClientID;
}
}

Categories