I saw this error twice recently, but as often happens for two completely different cases so here they are, hope it helps someone to same their time…
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
Nested forms
The first problematic application was dynamically building page layout and manipulating the HTML stream sent to the client; in my specific case there was some manipulation carried on the client through Javascript, but I think the same may happen if for example the HTML stream is changed through an HttpHandler after the main ASP.NET processing has been completed. The page was rendered correctly within the browser, but a postback thrown the exception above and this was due to a malformed page structure, where we had nested <form> tags like in the following example:
<body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" Text="Button" /> <form></form> </div> </form> </body>
There was a bug in the page, so the solution is to fix it to avoid the nested <fom> tags.
Hidden postback control
Here we had a DataGrid and on the ItemCreated event the customer was calling Item.Attributes.Add() to add a call to __DoPostBack() and have an automatic postback when a record was selected; needless to say, the postback attempt returned the error at the beginning of the post.
The customer had defined a “Select” column with a button to actually select the row within the DataGrid and set the Visible property of this button to false; ASP.NET renders the button to select the record as a LinkButton. This also emits the __DoPostBack() javascript method and registers it for event validation calling ClientScript.RegisterForEventValidation(); as you can imagine, if the control is not visible (i.e. Visible=”false”) the control is not rendered and therefore is not registered for event validation. But the DataGrid uses that event anyway, which ultimately throws the error.
The solution in this case is to manually register each row for event validation with code similar to the following:
protected override void Render(HtmlTextWriter writer) { foreach (DataGridItem row in DataGrid1.Items) ClientScript.RegisterForEventValidation(row.UniqueID.ToString() + ":_ctl0"); base.Render(writer); }
The event validation must be registered within the Render() method of the page.
Also note that there could be different degrees of added complexity to this scenario: for example if the name of the control causing the postback is built dynamically and maybe the application has been migrated from ASP.NET 1.1 to 2.0, you have to be aware that the naming convention for dynamic controls has changed. ASP.NET 1.1 uses DataGrid1$_ctl2$_ctl0 while ASP.NET 2.0 uses DataGrid1$ctl02$ctl00. It is possible to control this behavior setting xhtmlConformance=”Legacy” (see xhtmlConformance); however note that reverting back to Legacy mode causes ASP.NET 2.0 to use a column (“:”) sign in control names for event validation, instead of the dollar sign (“$”) which uses for rendering.
Carlo
Quote of the day:
Read, every day, something no one else is reading. Think, every day, something no one else is thinking. Do, every day, something no one else would be silly enough to do. It is bad for the mind to be always part of unanimity. – Christopher Morley
One Comment
Pingback: