I'm coming from an ASP background and learning ASP.NET. I wanted to know whether AutoEventWireup property wireup the Control events also(like Button_Click) or just the Page events?
I read elsewhere in SO that if you set it to TRUE & also provide explicit event handlers, it'll be executed twice, Can you explain why this happens (since there is just 1 handler VS must recognize its already executed)?
Can you give Use Cases of setting it to False?
Would appreciate a code sample
Generally it is set to true, which means you do not need to wireup each even explicitly. You will set it to false when you want to use the same event handler for more than one controls/events. In that case you can explicitly wireup multiple events to single event handler. It controls all events. When you set the property to true and also wireup the events explicitly, .Net will fire the event twice, because delegate will be registered twice.
AutoEventWireup on the Page element works by looking for methods matching an expected signature and naming convention (i.e. Page_<event>). If found, the page framework will call the event-handlers directly before "raising" the event normally. This is why, if you register the event-handlers in code, they are effectively called twice.
This is quite different from how event handlers normally work. If you wrote code to register a handler with the same event twice, it will only be called once per event. This is because the event handlers are essentially a set of delegates and attempting to add a delegate to the same method is a no-op.
The AutoEventWireup behaviour only applies to events raised by the page. You won't get it for other controls, so they should be wired up manually, usually in a Page_Init or Page_Load event.
If you don't use AutoEventWireup (i.e. set it to "false"), you have to wire up the page event handlers yourself to get them to be called. This is what the Visual Studio designer does, since it generates event-registration code for you.
Related
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
I am pretty sure back in the days of ASP.NET 1.0/1.1, controls created during runtime needs to be added before Page_Load event of the Page Lifecycle (i.e. inside Page_Init).
Here's one article by Microsoft on it (for .NET 1.0/1.1):
HOW TO: Dynamically Create Controls in ASP.NET:
Note When you create dynamic controls
on a Web Form, you must create the
controls and add them to the controls
collection in either the Page_Init
event handler or the Page_Load event
handler. Otherwise, the controls may
not behave as expected.
However, in a few posts here, it seems like the above is not the case anymore. Controls added within Page_Load seems to be working for everyone else. Some of the posts include:
creating dynamic control in asp.net
Viewstate - utter confusion.
I've tried it myself and indeed it worked though I've not done enough test to fish out any unexpected behavior.
So is Page_Load a safe stage to add dynamic controls? Or is it only for .NET 2.0 and above?
I have studied this with Reflector, and the Control class does indeed bring things up to speed when you add them dynamically, no matter when you add them. It does everything - loads viewstate/controlstate, calls postback events, calls event handlers, etc. I don't know if it was different in ASP.NET 1.x days, but in 2.0 and above this is the case.
As for the "dangers" - there are some gotchas that the inexperienced user might trip over, so it is recommended that you add them in Page_Init or before. (Note that the PreInit event only applies to the page itself, not the Master Page or subcontrols). Off the top of my head (I'm sure there might be a few more):
By default viewstate loads positionally. That is, it ignores control IDs and just takes control placement in the tree into account when loading viewstate. If your dynamic controls were present when the viewstate was serialized, but are not present when it is deserialized, the wrong viewstate item might get assigned to the wrong control, thus leading to exceptions. This can be changed by some settings, though I'm now too lazy to search for them.
Since the "bringing up to speed" happens when the dynamic control gets added to the page, the order of some events might be unexpected. For example, if you add a TextBox control to the page in the Page_PreRender event, the Changed event of the TextBox will happen there and then. If your event handler code depends on the event happening with the rest of them before PreRender, then you are screwed.
You can add controls at any time. However, they'll only work with viewstate if you add them before page loads.
In fact, if you check the .Net 2.0 version of the page lifecycle link you posted, you'll stilll find this quote under the PreInit event:
Use this event for the following: ... Create or re-create dynamic controls.
The Page_Load event handler is an acceptable place to add controls. If you re-read your note you will notice that they state that.
Note: When you create dynamic controls
on a Web Form, you must create the
controls and add them to the controls
collection in either the Page_Init
event handler or the Page_Load
event handler. Otherwise, the controls
may not behave as expected.
If the ASP.NET 2.0 article you linked to, under "Catch-up Events for Added Controls", they discuss how added controls are brought up to speed with the page.
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
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.
Where in the page life cycle is it most appropriate to set event handler delegates for events raised by custom User Controls?
I have a ReportFilter user control that raises an ApplyFilterClicked event. Currently I am just using Page_Load to assign a handler method.
reportFilter.ApplyFilterClicked += reportFilter_ApplyFilterClicked;
If you are creating your user controls dynamically, then the most appropriate place is in the Init phase, right where the controls are created (or should be).
Otherwise, the Load phase will work just fine, and is probably where most people set them. Obviously, you can't set the handlers anywhere later than that, otherwise they would never be called, since the event handling phase is next in line after Load.
Usually the init phase is best for creating controls because this will help with viewstate updates to the controls. Check out this page for some good info on page lifecycle:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Hope this helps