Invalid postback or callback argument error when button click - Beginner - c#

I am getting the following error;
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.
I added a columm, and added a button into it, When the button is fired the following C# code gets executed;
ASP.NET Code
<Columns>
<%-- <asp:BoundField /> Definitions here --%>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="AddButton" runat="server"
CommandName="AddToCart"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Add to Cart" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
C#
protected void GridView1_RowCommand(object sender,GridViewCommandEventArgs e)
{
if (e.CommandName == "AddToCart")
{
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button
// from the Rows collection.
GridViewRow row = GridView1.Rows[index];
}
}
How do i get rid of this error;
I added <globalization requestEncoding="utf-8"/> but the error is still there.
`
UPDATE
<asp:GridView runat="server" ID="gdv" AutoGenerateColumns="True" OnSorting="sortRecord" AllowSorting="true" DataKeyNames="HotelName" CellPadding="4" Width="746px">
<Columns>
<%-- <asp:BoundField /> Definitions here --%>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="AddButton" runat="server"
CommandName="AddToCart"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Add to Cart" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

What I usually find myself using is a buttons OnClick events instead of the GridViewRowCommand. It's easier to work with for the most part. So your ASP would look like;
<asp:GridView runat="server" ID="gdv" AutoGenerateColumns="False" OnSorting="sortRecord" AllowSorting="true" DataKeyNames="HotelName" CellPadding="4" Width="746px">
<Columns>
<%-- <asp:BoundField /> Definitions here --%>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="AddButton" runat="server" OnClick="AddButton_Click" Text="Add to Cart" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And your c# would look like;
protected void AddButton_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
GridViewRow row = (GridViewRow)btn.NamingContainer;
}
Now in your code behind you can do anything you need to do with that row, and you know you'll be getting the row you want.
Hope this helps!

Related

How to prevent full page postback on selectedindexchange for dropdownlist

<asp:UpdatePanel runat="server" ClientIDMode="Static" ID="TasksUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="pnlDropDown" runat="server" ClientIDMode="Static" CssClass="pnlDropDown">
<!-- TASK NAME -->
<asp:DropDownList ID="ddlTaskName" CssClass="chosen-select" DataSourceID="dsPopulateTaskName" AutoPostBack="true" DataValueField="Task Name" runat="server" Width="100%" Font-Size="11px" AppendDataBoundItems="true" OnSelectedIndexChanged="ddlTaskName_onSelectIndexChanged">
<asp:ListItem Text="All" Value="%"></asp:ListItem>
</asp:DropDownList>
</asp:Panel>
<asp:GridView ShowHeaderWhenEmpty="false" AlternatingRowStyle-BackColor="#EBE9E9" AutoGenerateColumns="false" OnSorting="yourTasksGV_Sorting" AllowSorting="true" ID="yourTasksGV" runat="server" ClientIDMode="Static" EmptyDataText="You currently have no tasks assigned to you" OnRowDataBound="yourTasksGV_RowDataBound" OnRowCreated="yourTasksGV_RowCreated">
<Columns>
<asp:TemplateField HeaderStyle-Width="2%">
<ItemTemplate>
<asp:ImageButton ImageUrl="~/cies.png" runat="server" ID="btnShowDepend" OnCommand="btnShowDepend_Command" CommandName="TaskDepend" CommandArgument='<%#Eval("TestIt") %>' ToolTip="Click to view Dependencies" />
</ItemTemplate>
</asp:TemplateField>
<asp:HyperLinkField HeaderStyle-Width="16%" Target="_self" DataNavigateUrlFields="Task Detail" DataTextField="Task Name" DataNavigateUrlFormatString="" HeaderText="Task Detail" SortExpression="Task Name" ItemStyle-CssClass="taskTableColumn" />
<asp:BoundField HeaderStyle-Width="10%" DataField="Workgroup" HeaderText="Workgroup" SortExpression="Workgroup" ItemStyle-CssClass="taskTableColumn" />
<asp:BoundField HeaderStyle-Width="7%" DataField="Status" HeaderText="Status" SortExpression="Status" ItemStyle-CssClass="taskTableColumn" />
</Columns>
</asp:GridView>
</ContentTemplate>
<%--<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlTaskName" EventName="onSelectIndexChanged" />
</Triggers>--%>
</asp:UpdatePanel>
Whenever the ddlTaskName_onSelectIndexChanged function is executed there is a full page postback rather than just updating the UpdatePanel
ddlTaskName_onSelectIndexChanged function:
protected void ddlTaskName_onSelectIndexChanged(object sender, EventArgs e)
{
PullData(ViewState["sortExp"].ToString(), ViewState["sortOrder"].ToString(), false); //calls a function to update the GridView
}
With the above code, the page does a full postback rather than just partial (only update the GridView) whenever the index is changed in the ddlTaskName
What code can I add/modify to ensure the full postback isn't executed and only update the GridView on index changed.
Thought... Do I need to add them in two separate UpdatePanel?
If I uncomment the triggers, I get the following error: A control with ID 'ddlTaskName' could not be found for the trigger in UpdatePanel 'TasksUpdatePanel'.
I am attaching the dropdownlist to the Gridview like this:
Is it because of this:
protected void yourTasksGV_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView hGrid = (GridView)sender;
GridViewRow gvrRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableHeaderCell tcCellTask = new TableHeaderCell();
tcCellTask.Controls.Add(ddlTaskName);
gvrRow.Cells.Add(tcCellTask);
yourTasksGV.Controls[0].Controls.AddAt(0, gvrRow);
}
}
your code seems fine. did you try to comment out asp:Panel tab?
if you unccoment triggers, you need to put asp:UpdatePanel around gridview
As per this post it looks like your asp:Panel could be the culprit with the ClientIDMode="Static". Try changing this so it inherits.
You'd need to specify ChildrenAsTriggers="true" in your UpdatePanel tag. The error you're getting is because your dropdown doesn't physically exist in the markup, which is what a Trigger line expects to find during compliation/runtime - instead, you are adding it dynamically as a control in your RowCreated function. It might be possible to, in that same function, add a trigger to the UpdatePanel dynamically, if you wanted to try that, instead.

How do I Pass Multiple Selected Datagrid Values to Another Page in asp.net?

I have multiple asp.net data grids that a user can select a checkbox to the corresponding value that they want, put in the amount they want in a textbox and submit the request. How do I show what values they requested with the amount on the next page? I can do this with a session I believe but I'm having a hard time finding good examples for something like this. Since they can select multiple values I can't use a query string right? I'm using VB.net but if you answer in c# that's fine. Thanks!
<asp:GridView ID="flexGridView" DataKeyNames="ID" runat="server" AutoGenerateColumns="False" DataSourceID="FormSqlDataSource" CssClass="gridView" ClientIDMode="Static">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="flexCheckBoxList" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Form" ShowHeader="False" />
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" Visible="False" />
<asp:BoundField DataField="Category" HeaderText="Category" SortExpression="Category" ShowHeader="False" Visible="False" />
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lblEmail" runat="server" Text='<%# Eval("Email")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Qty" >
<ItemTemplate>
<asp:TextBox ID="flexTextBox" runat="server" Width="40" ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You can use Session or query string, but I would recommend Session, as there are limitations on the length of a query string, especially if you are not sure how many check boxes might be checked.
Use the OnCheckChanged event of the check box control and set AutoPostBack to true in your template field, like this:
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="flexCheckBoxList" runat="server"
AutoPostBack="True" OnCheckedChanged="Check_Clicked" />
</ItemTemplate>
</asp:TemplateField>
protected void Check_Clicked(Object sender, EventArgs e)
{
// Store the check box name, ID or whatever unique value you want in Session here
CheckBox theCheckBox = sender as CheckBox;
// Was the check box found?
if(theCheckBox != null)
{
// Store in Session
Session["CheckBoxValue"] = theCheckBox.SomePropertyValue;
}
}
Then in the Page_Load of your redirect page, you will need to read out the Session value for the checked check boxes.

grid posts back when checkbox is checked

I have this grid set up.... it all works totally fine... except one issue...
<asp:GridView runat="server"
ID="grdFacetsAssigned"
AllowPaging="false"
AllowSorting="True"
DataKeyNames="lngSystemFacet"
OnSelectedIndexChanging="grdFacetsAssigned_SelectedIndexChanging"
CssClass="table_scroll"
AutoGenerateColumns="False" GridLines="None"
ShowHeader="false" Width="500px"
OnSelectedIndexChanged="grdFacetsAssigned_SelectedIndexChanged"
ShowFooter="false" PagerSettings-Visible="false"
DataSourceID="SM_spStateUpdateReport_FacetAssignList"
OnRowCreated="grdFacetsAssigned_RowCreated">
<RowStyle CssClass="table_row" />
<Columns>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lbllngSystemFacetID" runat="server"
Text='<%# Eval("lngSystemFacetID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="strSystemSystemFacet" SortExpression="strSystemSystemFacet"
ItemStyle-Width="50%" />
<asp:TemplateField ItemStyle-Width="30%" ItemStyle-HorizontalAlign="Center"
SortExpression="bolAssigned">
<ItemTemplate>
<asp:CheckBox ID="chkFacetAssigned" runat="server"
OnClientClick="alert(this.checked);"
OnCheckedChanged="chkFacetAssigned_CheckedChanged"
AutoPostBack="True" Checked='<%# Eval("bolAssigned") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField SortExpression="intOrder"
HeaderText="Display Order" ItemStyle-Width="20%">
<ItemTemplate>
<asp:Label ID="lblAssignedFacetOrder" runat="server"
Text='<%#DataBinder.Eval(Container.DataItem, "intOrder")%>'></asp:Label>
<asp:TextBox ID="txtAssignedFacetOrder" runat="server"
CssClass="gridview_input"
Text='<%#DataBinder.Eval(Container.DataItem, "intOrder")%>'
Visible="False"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle CssClass="table_selected_row" />
<AlternatingRowStyle CssClass="table_alternating_row" />
<EmptyDataRowStyle CssClass="table_empty" />
<EmptyDataTemplate>
No Data
</EmptyDataTemplate>
</asp:GridView>
When you click the chkFacetAssigned checkbox the appropriate event fires. The code works well from there. What happens though is when the checkbox is checked... if the row is not selected there are two postbacks that happen. The first postback is from the grid and the second postback is from the checkbox. Both postbacks cause the chkFacetAssigned_CheckedChanged event to be called- resulting in code running twice that should only run once. I should note that if the row is already selected (the row the checkbox is on) you do not see this extra postback. Someone please help.
There are no other event handlers registered or anything like this.
First line of your code. Remove the following.
OnSelectedIndexChanging="grdFacetsAssigned_SelectedIndexChanging"
Second Line
OnSelectedIndexChanged="grdFacetsAssigned_SelectedIndexChanged"
What I did for this was a workaround in the checkbox event handler...
if (Page.Request.Params["__EVENTTARGET"].IndexOf("chkFacetAssigned") < 1)
{
return;
}
This ensures that the event is ignored unless it is responding to a postback that was initiated by the checkbox and not the grid.

Adding a button to the last column of a GridView

This is how i created a grid view in my ASP.NET C# project. This grid has 4 columns. I want to add a 5th column and add a button on each and every row. How can i do this ?
<asp:GridView ID="gv" runat="server" CellPadding="1" Width="900px"/>
Set AutoGenerateColumns="False" in the gridview markup
Define columns as BoundField (or TemplateField if you wish)
Add aTemplateField for the button in the last column
Sum up:
<asp:GridView runat="server" ID="gv" AutoGenerateColumns="False" CellPadding="1" Width="900px">
<Columns>
<%-- <asp:BoundField /> Definitions here --%>
...
<asp:TemplateField>
<ItemTemplate>
<asp:Button Text="Click ME" runat="server" ID="btn" OnClick="Clicked" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
suppose you are binding data table having 4 column say col1,col2,col3 and col4
then your gird view in .aspx will be like;
<asp:GridView runat="server" ID="gv" AutoGenerateColumns="False" CellPadding="1" Width="900px" OnRowCommand="gv_RowCommand">
<Columns>
<asp:TemplateField HeaderText="col1">
<ItemTemplate>
<%#Eval("col1")%>// "col1" is field of your database
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="col2">
<ItemTemplate>
<%#Eval("col2")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="col3">
<ItemTemplate>
<%#Eval("col3")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="col4">
<ItemTemplate>
<%#Eval("col4")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnOK" runat="server" Text="OK" CommandName="show" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
*.cs page will be *
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.ToLower() == "show")
{
//your code on click event
}
}

ASP.NET PostBack is not hitting the correct method

Consider the following ASP.NET code:
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:MultiView runat="server" ID="MultiView" ActiveViewIndex="0">
<asp:View runat="server">
</asp:View>
<asp:View runat="server">
<p><img alt="Loading..." src="/global/images/ajax-mini-loader.gif" style="vertical-align: middle;" /> Loading...</p>
</asp:View>
<asp:View runat="server">
<asp:GridView runat="server" ID="WarrantyView" OnDataBound="WarrantyView_DataBound" AutoGenerateColumns="false" ItemType="WarrantySystem.Data.ServiceCompany">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="Telephone" DataField="Telephone" />
<asp:BoundField HeaderText="Email" DataField="Email" />
<asp:BoundField HeaderText="Telephone 24/7" DataField="Telephone247" />
<asp:BoundField HeaderText="Email 24/7" DataField="Email247" />
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:Button runat="server" ID="btnEdit" CommandName="Edit" CommandArgument="<%# Item.ID %>" Text="Edit" />
<asp:Button runat="server" ID="btnDelete" CommandName="Delete" CommandArgument="<%# Item.ID %>" Text="Delete" OnCommand="btnDelete_Command"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:View>
<asp:View runat="server">
<p>Your data could no be loaded at this time.</p>
</asp:View>
</asp:MultiView>
<asp:Timer runat="server" ID="tmrLoadData" Enabled="true" Interval="1" OnTick="tmrLoadData_Tick" />
</ContentTemplate>
</asp:UpdatePanel>
When btnDelete is clicked, a postback event occurs to Page_Load, and never hits btnDelete_Command, as it should. I'm lost as to why!
EDIT: The same problem occurs with the edit button...Okay so in the example, there is no OnClick or OnCommand event, but I have just tested this...it does the same thing.
How it works:
The page loads and shows an empty view.
The timer ticks and begins loading data, and shows the data loading view.
Once the data loads, the data view shows.
When clicking edit, the page should redorect to the edit page.
When clicking delete, the page should just delete the entry.
EDIT: As per user comments (server-side code command code):
protected void btnDelete_Command(object sender, CommandEventArgs e)
{
bool result = this.mgr.DeleteServiceCompany(Int32.Parse(e.CommandArgument.ToString()));
}
protected void btnEdit_Command(object sender, CommandEventArgs e)
{
Response.Redirect("ServiceCompany.aspx?id=" + e.CommandArgument.ToString());
}
Use the RowCommand event of GridView to fire your Edit and Delete command.
Add this inside your GridView markup.
OnRowCommand="WarrantyView_RowCommand"
Also change the CommandName text
CommandName="Modify" // change the name here
CommandName="Remove" // change the name here
And inside the event
protected void WarrantyView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Modify")
{
// your edit logic
}
if (e.CommandName == "Remove")
{
// your delete logic
}
}
I did recommend you to change the name of the CommandName property.
Change Edit to perhaps Modify
Change Delete to perhaps Remove
Reason being they are inbuilt gridview commands
NOTE: Ensure that your ViewState is enabled in all relevant places too. This will not work with ViewState disabled.

Categories