Like in java the entry point is public static void main(String[] args). What is the entry point in ASP.NET using C#? Usually, I see the page load method, is that the entrance point?
Does asp.net follows some different criteria?
You need to take a look at the ASP.NET life-cycle:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
There is no "main point" in asp.net. What you would think of as "main" in asp.net is code that's already written for you. Instead, you inherit a base class ("Page"). As part of this, you can (but don't have to) implement several event handlers. Through the process of building a page, Asp.Net will raise these events for you to handle. The process of running through these events in order is called the page lifecycle.
For your case, there are several options depending on what you want the main method to do:
Handle the Application_Start event in the Global.asax file
The Page_PreInit event (the very first event in the page life cycle)
The Page_Load event (the most common event handled in the page life cycle)
You said something wrong.
public static void main() is a Java method too, used as entry point for console applications the exact way C# does.
You might want to compare servlets/JSP and ASP.NET, don't you?
Servlets vs IHttpHandler
They are, conceptually, the same thing. They are also both interfaces. Their configuration is different (WEB.xml VS Web.config or .ashx file), but their entry points are "almost" the same.
Servlet:
Init()
Service()
Destroy()
IHttphandler:
ProcessRequest() <<--- does all the things
IsReusable {get;} <<--- optional
JSP vs ASP.NET pages
If you define a constructor, or override the InitializeFramework() method, then you have a starting point (or, at least, a breakpoint to put at the almost-very-beginning of the execution), but not an entry point.
Page class implements IHttpHandler, if you allow me some Java syntax in .NET world, but you don't see anything. You might want to go deeper into page life cycle as linked by other users. Basically explaining, Page encapsulates its complete life cycle in events, that resemble clock ticks when you work with VHDL components.
Execution is not concurrent as it seems, but since you can't know the exact order in which controls will raise the same event, you can go as the VHDL example in which you can't read the value of a registry before the next clock tick.
There are several events: here are the most important in their execution order
Init: page is initialized, GET, POST and cookie data are available. If you override, then you should initialize your webapp context (ie setup db connections)
Load (PreLoad and LoadComplete too): page loads the UI data and restores, if needs to, the state of controls displayed on the page. If you set up DB connections in init, you shouldn't use them before PreLoad to be sure you don't get an exception. The same applies to sequence PreLoad->Load->LoadComplete.
DataBind: data-bound controls load data from database, file or whatever (ie. tables get the data to display)
Validation: if you use validators, their business logic is processed to determine whether the page is valid or not. No further explaining here
Postback processing: if you click a button, then its server-side code is executed
PreRender (and PreRenderComplete): the page is getting ready for being rendered into HTML. Usually stores internal data into a collection named ViewState which I won't explain any further here. Usually you would finalize some data-related operations and/or decide whether to render or not some controls on the page according to the page's state. For example, if you have a CAPTCHA and the user solved the puzzle, you won't render it again
Render: not actually a programmatic event, but the page gets rendered to HTML
Dispose: resources get freed, as occurs with Destroy in Java
Related
I am new to WebForms, I think I have a rather simple question.
I often see people initialize any kind of dependencies in the page_load-method of their page class. Is that a common thing to do ?
Things I would usually write in the constructor.
How do I decide what belongs in the constructor and what is better placed in the page_load handling method
You must take a look at asp.net life cycle.
On costructor method you can write lot of code, declaring variables and using classes and libraries.
But if you need some asp.net elements (Page, Controls, Session, QueryString etc) you need to be in Page_Load or in other methods of life cycle.
When an ASP.NET page runs, the page goes through a life cycle in which it performs a series of processing steps. These include initialization, instantiating controls, restoring and maintaining state, running event handler code, and rendering. It is important for you to understand the page life cycle so that you can write code at the appropriate life-cycle stage for the effect you intend. Additionally, if you develop custom controls, you must be familiar with the page life cycle in order to correctly initialize controls, populate control properties with view-state data, and run any control behavior code. (The life cycle of a control is based on the page life cycle, but the page raises more events for a control than are available for an ASP.NET page alone.)
I have an object, let's call it objK that has an event Message that accepts a string. I have a event handler in my code behind page called HandleObjKMessage(string s). that method looks like this currently :
void HandleObjKMessage(string s)
{
TextBox1.ReadOnly = false;
TextBox1.Text += s+ Environment.NewLine;
UpdateP.Update();
}
objK is an object from an external .dll(assembly) that is running an iterative process that I need to be keeping the user update from. That is the purpose of using an event.
Am i barking up the wrong tree? I'm typically a winforms guy and this is frustrating the hell out of me.
Thanks.
I might have misunderstood you, but you have an object that you instantiate, and then add an event handler to this object's event, and when the event fires you want the user to get the updated data?
If this is the case, it is not possible. This is simply because the web does not have state. There is no persistent connection between the server and the client.
When a request is received for your page, the server will create an instance of your page class, and run through the life-cycle (init, load etc.) Once the page has been rendered into HTML markup, the server disposes the instance of the page, and thus your attached event handler.
You can read more about the WebForms Page Lifecycle at MSDN
If you really want to go all the way and actually push the notification to your user, you could use SignalR, but this adds quite some complexity.
I have a UserControl A that has to be loaded first and after that completes loading, I need to load a UserControl B.
I prefer to add both these user controls on the page at compile time (would like to avoid dynamic loading if possible).
If I add user controls on the page at compile time and set visible to false for User Control B, does it still execute the B's code behind? I can then set the visibility to true after loading User Control A
Should I be using events/delegates for notifying the completion of loading User Control A?
Don't load everything in the page event in control b, just put a method on control b to be called. Then add an event to control a which the page consumes, when the event is raised, call the load method on control b.
Edit: SampleCode
Ok so for example, create
a ASPX page
2x user controls
Put both user controls into the aspx page.
<cc:control1 runat="server" id="control_one" />
<cc:control2 runat="server" id="control_two" />
Then in control 1, create a delegate and event.
public delegate void MyCustomEvent (EventArgs args);
public event MyCustomEvent MyEvent;
protected void Page_Load(object sender, EventArgs e)
{
MyEvent(e);
}
So I have the event raised on page load. So you would have your logic in there thats required, when your done, calls MyEvent event.
In the page you want to add a handler for that event so when it's called you can do something with it.
protected override void OnInit(EventArgs e)
{
control_one.MyEvent += new WebUserControl1.MyCustomEvent(control_one_MyEvent);
base.OnInit(e);
}
void control_one_MyEvent(EventArgs args)
{
control_two.MyCustomLoad();
}
So when the page is initialized I add the event handler. In the event handler I call a custom method on the second control to load stuff.
Then in the second control I have:
public void MyCustomLoad()
{
//Stuff only loaded when event is raised and calls this method.
}
So this allows control 1 to load something, say it's done, when the page knows it's done, it can tell control 2 to do something.
Edit: After discussing this with a friend I'll explain what I mean by controlling the order.
You cannot control the order of page-life-cycle events. i.e: You can't have Control A, run through all it's page-life-cycle events, then once it's done, have Control B run through all it's page-life-cycle events.
If you do-away with the page life cycle, you can do a degree, as my example above shows, create a way of controlling the order in which the controls are rendered. By raising an event(s) at certain points when Control A is finished, you can tell Control B to do something.
The intermediate between the two controls is the page which handles the events raised by Control A which calls a method on Control B. You (well you can hack around to do it) can't specifically make Control A tell Control B to do something because that creates a direct dependency between the two controls which is bad.
Yes, the code behind will still run
Events could be useful
But if your controls have a specific dependency on each other, maybe they should just be a single control?
This is a fatally-flawed design. You should design your UI so that it doesn't matter in what order the controls load. The order in which controls load is outside of your control.
To address "Phill's" issue with an Order/Orderlines control pair:
I assume that the Order control was developed because it's useful by itself. I assume that OrderLines was developed to be able to show the line items for a given order displayed by the Order control.
I contend that there should be a single, composite control which combines Order and OrderLines. this control will pass to the OrderLines control, a DataSource consisting of the line items it is to display. This makes OrderLines independent of any other control - it simply displays the data it is told to display. It has no idea where that data came from.
Note that this can extend to a typical grid / detail / detail lines scenario, where you pass the grid a set of orders; when selected, a particular grid row will pass the Order control the selected order; when its' time to display the line items, pass the line items collection of the current order to the OrderLines control, etc.
This leaves each control with nothing to do but the Single job it is Responsible for.
"I have a UserControl A that has to be loaded first and after that completes loading, I need to load a UserControl B.
I prefer to add both these user controls on the page at compile time (would like to avoid dynamic loading if possible). "
I would suggest using WebFormsMVP: -
http://webformsmvp.com/
http://wiki.webformsmvp.com/index.php?title=Main_Page
As well as being a good implementation of Model-View-Presenter, one of the most useful features of this framework is its support for Messaging.
In a nutshell, you create Message Types, and your usercontrols (views) can post messages of whichever type you need to a message bus. Other controls can subscribe to messages of a particular type and the WebFormsMVP framework will ensure they are delivered.
This allows you to handle interaction between usercontrols by messaging publish & subscribe, without worrying about which order they load in.
Your only other option is to use dynamic control loading because, as others have pointed out, you can't rely on the order in which ASP.NET loads controls into a container.
I'm looking for a way to intercept the ASP.NET processing pipeline in such a way to be able to register event handlers to all events on the Page class. The reason is, I need to maintain a session-bound instance of a component that needs to be notified of all important Page events, starting from OnPreInit.
There's an arbitrary number of Page descendants in the application, which are not under my control. Hence I cannot use an approach like using a single custom descendant, that would notify the session-bound component, as a base class for all pages in the web application.
I don't think creating a custom IHttpHandler or IHttpModule implementation would solve the problem. Also note I cannot create a custom HttpApplication descendant.
It isn't going to be an elegant process to do what you are looking at, especially if you need to handle multiple page events, but in theory it is fully possible from within the Global.asax to setup handlers that you need for each and every page.
The trick here is to add your code to the global.asax in the PreRequestHandlerExecute method, from here you can get access to the HttpApplication object, get access to the page from there, and then register your events. This process is necessary as a new page instance is created for every page that is processed.
Now, other options as you know are far more elegant, but this should get to where you need to be. One helpful tutorial I found although around Themeing shows you the whole process here.
EDIT:
After seeing your comment, yes, you can simply do what I'm stating above, in a custom HttpModule. The article I linked even shows you that process :)
Without knowing more about what you're trying to accomplish it really sounds like you do indeed want to create a http module or handler. You might want to take a look at this question
Previously Called: How to deal with dynamically created controls under load in aspx
in response to a question below: the information required to determine which controls to restore is contained in a dedicated viewstate object.
I am dynamically creating controls in the codebehind page - these controls are all hooked up to click handlers so when a postback occurs I must re-create the previous set of controls, then clear the controls down and generate the new set of controls based on the previous click.
This is coded and working correctly under normal circumstances esentially as follows:
in Page_Load
if not postback generate default buttons
else if postback re-generate buttons that were shown on last page
in click_handler
Clear the dynamically generated buttons created in the Page_Load
generate new buttons based on the specific click being handled
however when the server comes under load we start getting problems:
With 5 users per second we start getting the exception:
Multiple controls with the same ID 'add0' were found. FindControl requires that controls have unique IDs.
With 100 users per second we start getting the exception:
The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.
Once this occurs all subsequent requests get the same error and IIS has to be re-started.
What could be causeing this and how can I avoid it? Do html requests possibly overwrite and interfere with each other when under load? do objects somehow hand around after a page unload in a manner that would allow the next page load to trip over them?
How are you storing information about the controls you need to restore? If you are using ViewState or ControlState, then I don't see how load could affect things. That's how any of the composite controls do things.
I will say that I saw your second error while using the Infragistics UltraWebGrid, and never was able to track it down. From the call stack, it appeared that EnsureChildControls was being called during the Load phase (or maybe LoadViewState).
A private static variable was being used to store a dictionary of names and table cells so that table cells would not get re-created during the page lifecycle.
The key point is that it was marked static - it should have been an instance variable - the end result being that under load when requests started backing up then multpile requests were sharing this static dictionary.
exactly what happened i'm not 100% sure - but under medium loads FindControl would find multiple controls of the same name, under very high loads it seems one request would try to modify a control (probably add to it) while it was in an invalid state from the other request.
End result - if you dont really know what your doing - prefer instance variable sto static variables.
Everything you have written seems to be correct and doable. Most likely this is an issue with your control generation code. Perhaps if you post some of that we can better find a solution.