Gridview OnRowDeleting event won't fire when EnableEventValidation = false - c#

I'm using a gridview, there is no problem binding it and filling it with data from code-behind. But now I want to use the OnRowDeleting event so that I'm able to delete a row from my gridview.
When I press the delete button I got this error:
0x800a139e - JavaScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
So I added EnableEventValidation = false, then when I pressed the delete button nothing happend at all. The event wasn't fired (checked with a breakpoint at GridView1_RowDeleting).
How can I make the event fire without any problems?
My gridview:
<asp:GridView ID="GridView1" runat="server" OnRowEditing="GridView1_RowEditing"
AllowSorting="True" AutoGenerateColumns="False" SkinID="gridviewGridlinesSkin"
OnRowUpdated="GridView1_RowUpdated" OnRowUpdating="GridView1_RowUpdating"
OnRowDeleted="GridView1_RowDeleted" OnRowDeleting="GridView1_RowDeleting"
EmptyDataText="No positions found" OnRowDataBound="GridView1_RowDatabound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ibEdit" runat="server" AlternateText="Edit"
CommandName="Edit" ImageUrl="~/Images/icon_edit.gif" />
<asp:ImageButton ID="ibDelete" runat="server" AlternateText="Delete"
CommandName="Delete" ImageUrl="~/Images/icon_delete.gif"
OnClientClick='<%# Eval("strPositionName", "return confirm(\"Are you sure you want to delete this entry {0}?\");") %>' />
</ItemTemplate>
<ItemStyle Wrap="False" />
</asp:TemplateField>
//Some controls here
</Columns>
</asp:GridView>
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//Make delete with the values from the row but event won't fire
}

Related

Event in Update panel is not fired after rebinding control after Postback

I have a Gridview together with some LinkButton inside of an Update Panel. The click events are fired correctly, the way I expect them to work. BUT: After adding an additional Header Row to the grid in code behind, I need to rebind the Grid after each postback. Since then the click causes a postback, but the method is not executed.
<asp:UpdatePanel runat="server" ID="UpdatePanel2" UpdateMode="Always">
<ContentTemplate>
<asp:GridView ID="GridViewFollowUpMove" runat="server" AutoGenerateColumns ="false" OnRowDataBound="FollowUp_RowDataBound" OnDataBound="FollowUpMove_OnDataBound">
<Columns>
<asp:TemplateField HeaderText="Due date" ItemStyle-HorizontalAlign="left">
<ItemTemplate>
<asp:LinkButton ID="LB_DueDate" runat="server" OnClick="ActivateDueDate" CssClass="NoDeco" CommandArgument='<%# Bind("ISSUEID") %>'>
<asp:Label ID="LabelDueDate" runat="server" Text='<%# Bind("DueDate","{0:dd.MM.yyyy}") %>' Width="60px" Class="line"/></asp:LinkButton>
<asp:TextBox ID="TXTBX_DueDate" runat="server" Text='<%# Bind("DueDate") %>' Font-Size="11px" visible="false" OnTextChanged="TextChanged_DueDate" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
FillFollowUp();
}
FillFollowUp();
}
I solved this problem by moving the commands that create and customize the additional Header row to the OnRowCreated Event. As I read somewhere: When a postback occurs, the Gridview must be recreated on the server, and in this process ItemCreated is fired for each item, but ItemDataBound is not (since the control properties are pulled from ViewState).
So building these headers in DataBound is the wrong choice!

FileUpload control retrieve null value in code behind?

I've a fileupload control and I want to get filename in codebehind. I'm using editindex event when I choose file and press editindex button then I'm getting null value of fileupload.
Here is my aspx code:
<asp:GridView ID="comp_gr" runat="server" AutoGenerateColumns="false" OnRowEditing="comp_gr_RowEditing">
<Columns>
<asp:CommandField ShowEditButton="true" ButtonType="Button" EditText="Complete Task" ControlStyle-BorderColor="White" ControlStyle-BorderStyle="Double" ControlStyle-BackColor="#990000" />
</Columns
<Columns>
<asp:TemplateField HeaderText="Attach Document">
<ItemTemplate>
<asp:FileUpload ForeColor="Black" ID="FileUpload1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And here is my codebehind
protected void comp_gr_RowEditing(object sender, GridViewEditEventArgs e)
{
FileUpload file = (FileUpload)comp_gr.Rows[e.NewEditIndex].Cells[1].FindControl("FileUpload1");
string f = file.FileName.ToString();
}
But I'm getting always null value in f.
you should place your FileUpload control in <EditItemTemplate> field instead of <ItemTemplate>.
If you don't know about it kindly google about it.
You should manage the file upload control in OnRowEdit event of the gridview.
Is the Grid (and with the the FileUpload control) in an UpdatePanel? If so, that's where your problem lies. Either remove the updatepanel or set the save button or whatever is causing the postback to be a PostBack control instead of an async postback control.

ASP.NET LinkButton not invoking 'OnCommand' event

I have a ListView nested inside the column of a GridView, which looks something like this:
<asp:panel id="myPanel" Runat="server" EnableViewState="False">
<asp:GridView id="myDescription" AutoGenerateColumns="False" Width="100%" runat="server"
OnRowCommand="my_RowCommand" OnRowDataBound="GetDataForListView" EnableViewState="False">
<Columns>
<asp:BoundField DataField="id" HeaderText="ID">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data1" HeaderText="Thing 1">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data2" HeaderText="Thing2">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data3" HeaderText="Thing3">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:TemplateField SortExpression="id">
<ItemTemplate>
<asp:HyperLink id="hlView" runat="server" NavigateUrl="...">View</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column to contain my list of things">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate>
<% /* This is my list view: */ %>
<asp:ListView ID="myListView" runat="server" OnItemCommand="DoSomething" EnableViewState="False">
<ItemTemplate>
<asp:LinkButton ID="lbAttachment" Runat="Server" Text='<%# Eval("FILE_NAME") %>'
CommandName='<%# Eval("ROW_NUM") %>' CausesValidation="False" >
</asp:LinkButton><br/>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:panel>
The data is successfully binding, but the OnCommand event is not being fired on clicking the LinkButton (nor is any other event for the LinkButton, such as an OnClick event).
The rendered HTML for the link button shows that on clicking it, the page is performing a postback: javascript:__doPostBack('...','')
This means it is going back into my 'Page_Load' and refreshing the contents of the page - the grid view is binded here.
I can stop it from performing a postback by adding this attribute to the LinkButton:
OnClientClick="return false;"
But this only stops the postback from occurring, the OnCommand event still doesn't fire.
Any ideas?
The event signature in the code-behind is:
protected void DoSomething(object sender, CommandEventArgs e) { ... }
I have also tried using an OnItemCommand event on the ListView control with this event signature, but similarly the event is not invoked:
protected void DoSomething(object sender, ListViewCommandEventArgs e)
The OnRowdataBound event on the parent GridView is successfully invoked, it's only the nested ListView that fails to invoke its event.
The code I have shown is for the 2nd GridView on the page, there is another one too, and it is this one which gets binded on the Page_Load event. The Page Load event has a sequence of events as follows, where the 1st GridView (which we'll call GridView1) is bound:
Page_Load
Data for GridView is retrieved from database
Data is assigned to a 'DataView' object and assigned to the GridView1 DataSource property.
GridView1.DataBind() is invoked
Miscellaneous conditional logic which removes certain columns from GridView1
An OnClick attribute is added to each row.
So actually, the Page_Load binds the first GridView. The 2nd GridView is the one which contains the ListView which I am having a problem with. This 2nd GridView (the code of which is at the top of the post) is populated on the 'OnRowCommand' event of the 1st GridView, and has a sequence like this:
GetDataForListView
Get data from database
Assign the DataSet containing the data to the DataSource property of the 2nd GridView
Call the DataBind() method
Then, as you can see from the code I posted at the top, I have the OnRowDataBound event which fails to invoke its event in the code-behind.
Ciaran, I replicated the whole scenario and found out the below issue.
Issue: When any event related to either the GridView2 or ListView or the LinkButton is being fired it first hits the Page_load function. In the Page_load function you are not data binding GridView2 and the ListView so apparently they almost vanish and so the Event will not be fired.
Possible Fix:
You need to bind the GridView2 in the Page_load function in order fire those related events and the same goes with the ListView Too.
This fix is a very big one. I am not sure if you could try this.
a. If you are binding the GridView2 depending on the condition generated by the GridView1 click then store those parameters in some hidden field.
b. Have a function named LoadGridView2(parameters) where you bind the GridView2 and the ListView depending on the parameters passed and call this function in the Page_Load function each every time a PostBack is done and pass the stored parameters in the hidden field to the LoadGridView2(parameters)
c. By doing above you can bind the GridView2 according the GirdView1 Click condition and make the GridView2 and ListView available in the PostBack too. So now the event could be fired.
Let me know in case of any queries.
LinkButton has OnCommand, ListVIew has OnItemCommand. So the name isn't correct. OnCommand only fires if the LinkButton has a CommandName set. And also, the repeater may swallow the button's command argument. Certain controls do that because of the way events bubble up to the UI.
<asp:LinkButton ID="linkButton" Runat="Server" OnCommand="DoSomething"
CommandName="DoSomething"
CommandArgument='<%# Eval("ROW_NUM") %>' Text='<%# Eval("FILE_NAME") %>'>
</asp:LinkButton>
Or Try adding:
<asp:ListView .. OnItemCommand=".." />
And then do:
void DoSomething(Object Sender, ListViewCommandEventArgs e) {
// Do something
}
Your button would still need to set a command name like:
<asp:LinkButton .. CommandName="DoSomething" />

PostBackTrigger on multiple LinkButtons in an update panel

I have a search form in an updatePanel which retrieves a list of users in a grid in the same UpdatePanel. The name of each user is a commandLink. I want to make the commandLinks as PostBackTriggers.
But when I do it I get an error at the pageLoad time that the controlId does not exist and its true because the grid of users does not render at the load time but through an ajax call.
Any ideas on how can I make the multiple command buttons in a grid retrieved through ajax call as post back triggers?
When adding the items to the grid, within the ItemDataBound event handler, you should register the postback for each specific control (the static identifiers in your HTML declarations are essentially placeholders - not all things repeated in the grid can actually have the same ID). You do this using the ScriptManager.RegisterAsyncPostBackControl method:
The RegisterAsyncPostBackControl method enables you to register Web
server controls as triggers so that they perform an asynchronous
postback instead of a synchronous postback. When the
ChildrenAsTriggers property of an UpdatePanel control is set to true
(which is the default), postback controls inside the UpdatePanel
control are automatically registered as asynchronous postback
controls.
As stated above, using ChildrenAsTriggers is a possibility, too, but this is commonly set to false for more stringent management.
I have found the solution. Here is the code on asp
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" OnClick="btnSearch_Click" Text="Search" />
<asp:GridView ID="gvSearchResult" runat="server" OnRowCommand="gvSearchResult_RowCommand"
OnRowDataBound="gvSearchResult_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:LinkButton ID="lnkbtnDetail" runat="server" CommandArgument='<%# Bind("CNIC") %>' CommandName="Detail">
<asp:Label ID="lblName" Text='<%# Bind("Employee_Name") %>' runat="server</asp:Label>
</asp:LinkButton>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" VerticalAlign="Middle"Height="25px"Width="30%" />
</asp:TemplateField>
</Columns>
</asp:GridView>
Ihad to place OnRowDataBound="gvSearchResult_RowDataBound" on gridView and that function looks like below. So I had to register the iterative control in Scriptmanager as PostBackControl in RowDataBound event of GridView.
protected void gvSearchResult_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if ((e.Row.RowType == DataControlRowType.DataRow))
{
LinkButton lnkbtnDetail = (LinkButton)e.Row.FindControl("lnkbtnDetail");
ScriptManager.GetCurrent(this).RegisterPostBackControl(lnkbtnDetail);
}
}
catch (Exception ex)
{
}
}

How to set gridview template field as target control for modal popup extender?

Is there a way to set control (in template field of gridview) as target control for modal popup extender? I tried like here:
Full postback triggered by LinkButton inside GridView inside UpdatePanel
But I get an exception as value parameter can't be null. Please help in detail.
Grid:
<asp:GridView ID="grdTemp" runat="server" AllowPaging="True" AllowSorting="True"
DataSourceID="SqlDataSource1" AutoGenerateColumns="False" DataKeyNames="TempNo" OnRowCommand="grdDULead_RowCommand" OnRowDataBound="grdDULead_RowDataBound">
<FooterStyle BackColor="White" CssClass="GridFooter" />
<Columns>
<asp:TemplateField><ItemTemplate><asp:LinkButton ID="grDULeadlnkSelect" runat="server" ForeColor="Red" OnClick="grDULeadlnkSelect_Click" CausesValidation="False" CommandName="selectrow">select</asp:LinkButton></ItemTemplate>
</asp:GridView>
Extender:
<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server" TargetControlID="grDULeadlnkSelect" PopupControlID="pnlCDAMTClar" BackgroundCssClass="modalBackground">
</cc1:ModalPopupExtender>
Code-behind:
At the start I got the error could not find control "grDULeadlnkSelect". Then I tried to register button like so but I get the error value cannot be null.
protected void grdTemp_RowDataBound(object sender, GridViewRowEventArgs e)
{ // getting err at below line.
LinkButton lb = e.Row.FindControl("grDULeadlnkSelect") as LinkButton;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);
}
What you can do is just set a dummy control ID as TargetControlID for the ModalPopUpExtender and make that dummy one invisible.
Now on RowCommand event of that GridView write:
ModalPopupExtender1.Show();
Hope this will solve your problem.

Categories

Resources