Reputation: 1
I try to pass this movieID and navigate to edit page including delete, but when I clicked the button, this situation occurred.
Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> 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.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
I can't do this because I need to make sure the page is secure
<%@ Page EnableEventValidation="false" %>
This is my code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="movieID" HorizontalAlign="Center" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:BoundField DataField="movieID" HeaderText="ID" SortExpression="movieID" ReadOnly="True" />
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<div class="text-center">
<asp:Button ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" CommandArgument='<%#Eval("movieID") %>' Text="Edit"/>
<asp:Button ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" CommandArgument='<%#Eval("movieID") %>' Text="Delete"/>
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
int movieID = Convert.ToInt32(e.CommandArgument);
if (e.CommandName == "Edit")
{
// Redirect to edit page
Response.Redirect("edit.aspx?movieID=" + movieID);
}
else if (e.CommandName == "Delete")
{
// Redirect to manager page
Response.Redirect("delete.aspx?movieID=" + movieID);
}
}
Upvotes: 0
Views: 34
Reputation: 49039
Ok, it not clear why you want (or need) the CausesValidation="false".
And also, I would consider dumping the Rowcommand of the GridView (Rowcommand is not all that great to use, since each command requires some if/then/else to process). Just use a standard good old regular asp.net button, and a button click event. You don't need anything more.
Also, for reasons of security, there is no need to show, include or display the movieID. This "id" has little or no meaning to the end user. And for reasons of security, exposing such database "id"'s means a user can with great ease change that id, and that's a security issue.
So, say this GridView markup:
<asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover"
Width="45%">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Edit"
ItemStyle-HorizontalAlign="Center"
HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="120px">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server"
Text="Edit"
CssClass="btn"
OnClick="cmdEdit_Click"
/>
<asp:Button ID="cmdDelete" runat="server"
Text="Delee"
CssClass="btn"
OnClick="cmdDelete_Click"
style="margin-left:5px"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Note how we just dropped in 2 buttons. And note how we do not show, expose, or even have the database PK id in the markup.
And the code behind is this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
string strSQL =
"SELECT * FROM tblHotelsA ORDER BY HotelName";
GVHotels.DataSource = General.MyRst(strSQL);
GVHotels.DataBind();
}
protected void cmdEdit_Click(object sender, EventArgs e)
{
Button cmd = (Button)sender;
GridViewRow gRow = (GridViewRow)cmd.NamingContainer;
int PK = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
Response.Redirect($"edit.aspx?movieID={PK}");
}
protected void cmdDelete_Click(object sender, EventArgs e)
{
Button cmd = (Button)sender;
GridViewRow gRow = (GridViewRow)cmd.NamingContainer;
int PK = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
Response.Redirect($"delete.aspx?movieID={PK}");
}
So, what is nice in above is that we enjoy a simple button click event, and for each button we add to the GridView, we don't care about the "row command", and we also don't have to show nor expose the database PK id in the markup.
In fact, I have quite an aversion to using URL so called query parameters, since it makes the URL look ugly, and users can with great ease change the "id" value in the URL.
Hence, I would use session to pass the value(s) to the next page.
Hence this:
protected void cmdEdit_Click(object sender, EventArgs e)
{
Button cmd = (Button)sender;
GridViewRow gRow = (GridViewRow)cmd.NamingContainer;
int PK = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
Session["MovieID"] = PK;
Response.Redirect($"edit.aspx");
}
Then in the page load event of the target page, I can pick up the PK database value like this:
int moiveid = (int)Session["MovieID"];
// rest of edit or delete code here
So, I would remove the causes valuation = false, it is not required.
And I would use separate event stubs for the buttons, and you can pick up the current GridViewRow with "naming container". Naming container works for Repeaters, ListView, GridView etc. (works for all data bound controls).
Thus, you don't need to expose the moveid in the markup (use datakeys setting). You don't need to pass the movieid to the button click. And you don't need to use the GridView RowCommand either.
And if you use session[], then you don't need to include or show the movieid in the URL either.
As noted, the target page for this test is this:
<h3>This is the delete page</h3>
<h3 id="myheading" runat="server"></h3>
And code behind:
protected void Page_Load(object sender, EventArgs e)
{
int moiveid = (int)Session["MovieID"];
myheading.InnerText = $"page to delete moveid = {moiveid}";
}
And thus, the result is this:
Upvotes: 0