ASP.NET Event Handler problem on Postback - asp.net

Hi I have a bit of a doozie.
I have a control with a click event attached. As far as I can see the event should be raised during postback. Things I have checked:
The __Eventtarget is correct.
The __EventArgs is correct.
The control can be found by using page.findControl([string in __Eventtarget]) after init, after load and during prerender.
I can cast the found control to IPostBackEventHandler and raise the event manually and it works fine.
What am I missing so the framework can handle this event?
Suggestions on a postcard or below please

I found the problem: it was a third party control registering itself requiring a raise event. This information was found by using custom class inherited from Page, overrode RegisterRequiresRaiseEvent and placing a break point on entry of the overrode sub.
Public Class Page
Inherits System.Web.UI.Page
Public Overrides Sub RegisterRequiresRaiseEvent(ByVal control As System.Web.UI.IPostBackEventHandler)
If TypeOf control Is Infragistics.WebUI.UltraWebGrid.UltraWebGrid Then Exit Sub
MyBase.RegisterRequiresRaiseEvent(control)
End Sub
End Class

Without the code here's a few things that may be causing problems:
Control is being added to the hierarchy late in the request cycle (and after the event has fired). This is problem if you're dynamically creating controls (including those in a data bound control like a Repeater, ListView, GridView, etc)
The event handler is being added in the code behind not the front end, eg: myButton.Click += new EventHandler(myButton_Click), and that is not being done on every request. It could be behind a logical path not executed

You have to make sure that the event is wired up in the request cycle. You can do this using the following methods:
Set AutoEventWireUp page directive as true which indicates if asp.net page event are added automatically
Set the Event Handler in code using the InitializeComponent function.
There are other possible ways to wire up the events, e.g. you could do it manually in your code somewhere. But I've found these 2 options to be the safest so that you will be sure that your events will be fired

Related

why asp.net dynamic charts are rendered only after the second page_load?

I am using web forms to develop a web application.
From the very beginning, I have always been surprised by the page_load event being fired twice, and finally today I found out that all gridviews and texts are rendered after first page_load, and it takes another page_load to render all the dynamic asp.net charts..
why is it so, is there an attribute on the chart web server control that I can use to bypass this?
Check to see if you "AutoEventWireup" set to true. If this is a control, check the parent control/page also. Even if the control itself is set to false, but the parent is set to true, it seems to fire anyway.
Also check where you assign listener to Page_Load event:
this.Load += new System.EventHandler(this.Page_Load);
Should be in InitializeComponent method

se the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation

guys, I have a usercontrol in my asp.net 3.5 application and I am passing some plain text on button click event. button is situated in the usercontrol. but when I fire the event, 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.
when I set the EnableEventValidation="false" to web form page like blow. it fires the event;
<%# Page EnableEventValidation="false" %>
but I am thinking that it shouldn't be a good idea to set that false. So, what is the alternative here? there error saying that 'use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.' but where am I gonna register that thing? thanks !
Also, I am using some AjaxControlToolkit controls inside my usercontrol and some jquery stuff.
try
if (!Page.IsPostBack)
before load and bind data in datagrid
The problem with ASP.NET 2.0 event validation is that it is all or nothing and a bit heavy handed. I read an article that explains what you should do here.
Basically you need to register the child controls of the user control with the event validation engine.
C#
protected override void Render(HtmlTextWriter writer)
{
// Register controls for event validation
foreach (Control c in this.Controls)
{
this.Page.ClientScript.RegisterForEventValidation(
c.UniqueID.ToString()
);
}
base.Render(writer);
}
VB
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
For Each aControl As Control In Me.Controls
Me.Page.ClientScript.RegisterForEventValidation(aControl.UniqueID.ToString)
Next aControl
MyBase.Render(writer)
End Sub
Now this may not solve your problem because I am not sure how you are returning the string. Another article explains that the event validation is a combination of the control's unique ID and all the values it can pass back. If you are using the command value of a button to pass the text you may have trouble with this task.
If the event that is causing the issue is the click, then registering the controls of the user control should do the trick.
In my situation I was trying to update a GridViews datasource on page_load and I forgot to check if the request was a postback, thus my source was trying to change and it threw this error. Once I did the check for post back it worked fine. Hope this helps someone in the future.
if (Page.IsPostBack == false)
{
this.sqlObj = new SqlServer(ConfigurationManager.ConnectionStrings["PdfReceiverConnectionString"].ToString());
this.populateDataGrid();
}
You can leave it enabled then register your control for event validation. Add the following call in the PreRender or Render page life cycle then your control should work without having to turn off eventValidation:
Page.ClientScript.RegisterForEventValidation(this.UniqueID);
Check your HTML, nested from Tags will also cause that

What exactly does a server control e.g. a TextBox do, around the time it fires its Init event?

My understanding is a server control's constructor is called by the page's constructor. This happens before Page_PreInit event. A server control's Init event fires after Page_PreInit. It seems a server control does not do much during the Init stage? Then why bother giving much emphasis to Init stage?
The server control constructor is called in Page.ProcessRequest, which is after the Page's constructor has fired. You are correct that the initial control tree is completely created by the time Page_PreInit is called. Initializing a control in its constructor is too early for many controls, because Control.Page is null (it is set after the server control is created and the control is added to the control tree).
TextBox doesn't make much use of the earlier parts of the page lifecycle. Other controls, like GridView or the Repeater, do though. The key difference between Init and Load, is that Init occurs before viewstate is loaded, and Load occurs after. You're not going to understand the purpose of Init until you truly understand viewstate.
I'm not entirely sure this is what you're looking for but a TextBox control inherits from System.Web.UI.WebControls.WebControl which in turn inherits from System.Web.UI.Control which is the object that defines the Init event regardless of whether the TextBox control requires it or not.
Whether this event is used or not depends on the requirement of the control inheriting this object. If you were wanting to create a custom web control and you needed to do something at the initialisation stage then you can access this stage via the OnInit method.
Hope this helps.

purpose for <pages enableEventValidation="false">

I've used the following in web.config
<pages enableEventValidation="false">
This corrects a problem we've been having with Ajax.
We have a web page that if you browse to directly using a standard HTML hyperlink works fine.
If you browse to the page from another page via link inside a gridview and response.redirecting in the RowCommand event to the page passing an ID in the querystring. The page throws errors from controls inside the panel stating
"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'm happy to leave the page validation as false as it seems to have had no other effect.
Any ideas what's happening?
Read the documentation.
EDIT: For security reasons, it's probably best to leave it set to true wherever you can.
I would therefore recommend that you set it to false only on the individual AJAX pages where it causes problems, while leaving it true in web.config.
From here
Invalid PostBack or CallBack argument error is basically raise because of Event Validation feature. The EventValidation feature is a new feature in ASP.NET 2.0, and provides an additional level of checks to verify that a postback from a control on the client is really from that control and not from someone malicious using something like a cross-site script injection to try and manipulate things. It is part of our overall strategy of increasingly adding security in depth levels to the programming model -- so that developers can be secure by default even if they forget to add security checks of their own.
Now, Invalid PostBack or CallBack argument error may occur when you are firing click event and the object is rebinding or its properties are changed in Page_Load event or someone is trying to hack into your system with cross site scripting. Each time .Net Framework render a page then it associate a unique Guid for all the controls. When binding a gridview or repeater, on each databind framework will associate a new guid for the contorl. So every time when you are firing event make sure Page_Load event does not change the control, because if the control changed the it will have a different Guid which have acutally fired the event for postback. Here are some scenario with this error.
1) Invalid Postback or Callback argument in GridView Problem may be: You are binding data in Page_Load event with either Object Data Source or Manual Binding with function call. This will make your GridView bind data on every event fire of any control. When you are firing any GridView command with OnRowCommand, before RowCommand fire your GridView will rebind and all control within it will be assigned to new id. So RowCommand could not get the item which have fired the event. Solution for Invalid Postback or Callback argument in GridView: You can bind your data within this if condition
if (!IsPostBack)
{
//Your code for Bind data
}
This code will definitely give you solution if this not work then check whether any other control is not giving error.
There is one thing worth adding here: If you want to disable the event validation for a specific control, rather than the entire page, there is a workaround documented here and here (and now referenced in the relevant Connect suggestion):
Simply subclass the relevant WebControl class, and don't set the SupportsEventValidation attribute on the subclass. The subclass will be exempt from event validation.

ASP.Net: User controls added to placeholder dynamically cannot retrieve values

I am adding some user controls dynamically to a PlaceHolder server control. My user control consists of some labels and some textbox controls.
When I submit the form and try to view the contents of the textboxes (within each user control) on the server, they are empty.
When the postback completes, the textboxes have the data that I entered prior to postback. This tells me that the text in the boxes are being retained through ViewState. I just don't know why I can't find them when I'm debugging.
Can someone please tell me why I would not be seeing the data the user entered on the server?
Thanks for any help.
This is based on .NET v1 event sequence, but it should give you the idea:
Initialize (Init event)
Begin Tracking View State (checks if postback)
Load View State (if postback)
Load Postback Data (if postback)
Load (Load event)
Raise Changed Events (if postback)
Raise Postback Events (if postback)
PreRender (PreRender event)
Save View State
Render
Unload (Unload event)
Dispose
As you can see, the loading of ViewState data back to the controls happen before the Load event. So in order for your dynamically-added controls to "retain" those values, they have to be present for the ASP.NET page to reload the values in the first place. You would have to re-create those controls at the Init stage, before Load View State occurs.
I figured out yesterday that you can actually make your app work like normal by loading the control tree right after the loadviewstateevent is fired. if you override the loadviewstate event, call mybase.loadviewstate and then put your own code to regenerate the controls right after it, the values for those controls will be available on page load. In one of my apps I use a viewstate field to hold the ID or the array info that can be used to recreate those controls.
Protected Overrides Sub LoadViewState(ByVal savedState As Object)
MyBase.LoadViewState(savedState)
If IsPostBack Then
CreateMyControls()
End If
End Sub
I believe you'll need to add the UserControl to the PlaceHolder during the Init phase of the page life cycle, in order to get the ViewState to be filled in by the Load phase to read those values. Is this the order in which you're loading those?
Ensure you are defining your dynamic controls at the class level and adding them to the ASP container:
Private dynControl As ASP.MyNamespace_MyControl_ascx
And when you instantiate the control, ensure you call LoadControl so the object is added properly:
dynControl = CType(LoadControl("~/MyNamespace/MyControl/MyControl.ascx"), ASP.MyNamespace_MyControl_ascx)
You have to create your controls in the Page_PreInit event handler. The ASP.NET server control model is tricky; you have to fully understand the page lifecycle to do it right.
As others have said, any form of control manipulation must be done before viewstate is created.
Here is a good link on the page lifecycle to help you out:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
We have experienced the same thing and have handled it by using ghost controls on page_load that have the exact same .ID and then the post back picks up the events and the data. As others said it's the dynamic adding of the control after the init stages that the state is built already and controls added after aren't stored.
Hope this helps a bit.
I also want to add that I've seen user controls work the way that you'd expect them to just by setting the Control.ID property at run time. If you do not set the ID, items may get built in a different order and work oddly.

Resources