ASP.NET中Invalid postback or callback argument问题求助(保留安全验证)
问题:GridView按钮触发Postback时的事件验证错误
出现的错误:
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.
当前代码:
ASPX页面代码:
<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>
后台C#代码:
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); } }
无需关闭事件验证的解决方法
方法1:通过GridView的DataKeys获取ID(推荐)
这种方式更安全,且天然符合事件验证要求,DataKeys由服务器端维护,不会被客户端篡改。
- 修改ASPX中按钮的
CommandArgument,传递当前行索引:
<asp:Button ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" CommandArgument='<%# Container.DataItemIndex %>' Text="Edit"/> <asp:Button ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" CommandArgument='<%# Container.DataItemIndex %>' Text="Delete"/>
- 后台修改
GridView1_RowCommand方法,通过行索引从DataKeys中获取movieID:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) { // 获取当前行索引 int rowIndex = Convert.ToInt32(e.CommandArgument); // 从DataKeys中取出movieID int movieID = Convert.ToInt32(GridView1.DataKeys[rowIndex]["movieID"]); if (e.CommandName == "Edit") { Response.Redirect("edit.aspx?movieID=" + movieID); } else if (e.CommandName == "Delete") { Response.Redirect("delete.aspx?movieID=" + movieID); } }
方法2:注册事件验证参数
如果坚持通过CommandArgument传递movieID,可在页面渲染阶段,将每个按钮的CommandArgument值注册到事件验证中,让服务器认可这些参数。
在后台添加重写的Render方法:
protected override void Render(HtmlTextWriter writer) { foreach (GridViewRow row in GridView1.Rows) { if (row.RowType == DataControlRowType.DataRow) { // 注册编辑按钮的事件验证参数 Button editBtn = (Button)row.FindControl("EditButton"); if (editBtn != null) { string arg = editBtn.CommandArgument; ClientScript.RegisterForEventValidation(editBtn.UniqueID, arg); } // 注册删除按钮的事件验证参数 Button deleteBtn = (Button)row.FindControl("DeleteButton"); if (deleteBtn != null) { string arg = deleteBtn.CommandArgument; ClientScript.RegisterForEventValidation(deleteBtn.UniqueID, arg); } } } base.Render(writer); }
修改后,事件验证会认可按钮传递的movieID参数,不再抛出错误。
内容的提问来源于stack exchange,提问作者user14876498
相关产品推荐
相关产品推荐

