ASP.net WebForms - Constructor vs. Page_Load - asp.net

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.)

Related

ASP.NET dynamically adding UserControl and cache data on postbacks

I have a Report.aspx page that loads different UserControls to view specific object data alternatively. The UserControls inherit the same base type class where override the specific operations methods. I use a specific Service class for each UserControl to get data which implements a specific interface with operations signatures.
I now use a factory pattern to return the actual UserControl type to the Report.aspx and load it into a PanelControl, then call the control method to fetch some data based on some arguments.
This UserControl should be loaded in every postback due to the dynamic nature of it, any other solution is accepted. On every postback though I don't need to load data from the BL which calls the DL. I try to find a solution to show to the BL that I don't need you to call for the data again because I'm just posting back for other issues (e.g. download a report file, print etc.). And I would like this to happen on the BL level, not the ASPX front end. So far I think that I should let BL somehow know this (PostBack or !PostBack). I guess I could just create a parameter true, false and pass the PostBack property.
Any ideas, architecture and best practices are so welcome.
why not wrap the logic to call the BL inside the if(!Page.IsPostback){....} ?
Can you elaborate your statement "On every postback though I don't need to load data from the BL which calls the DL."?? During each postback, user control needs data to show (even if it is same data as last postback) because usercontrol goes through same lifecycle as ASPNET webpage. How can you prevent that?
I have decided that a very nice solution is System.Runtime.Caching in .NET 4.0.
Works very nice for every layer you need to use it.
http://msdn.microsoft.com/en-us/library/dd985642

what is the main point to enter in asp.net?

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

ASP.Net MVC - What replaces events to support loose coupling?

What feature(s) of ASP.Net MVC can replace the way events can be used in Webforms to support loosely coupled components?
For example, take a simple pager control in Webforms:
A page number is clicked
Pager fires off a "PageChange" event with the new page number
This subscribing page/control received the event and handles initiating a call to fetch and bind new data.
What tools are available in ASP.Net MVC to similarly support
Loose coupling
Component re-usability
Separation of logic for a single page/view (such a very complex "portal" type page).
ASP.NET MVC, and the Model-View-Controller in general, support loose coupling and separation of concerns by keeping the data and code that supports an application separate from the visual "Presentation-layer" markup that is seen by users.
Designed properly, Controllers and Views in MVC can be reused so that the Edit View for an entity can be "embedded" into a related View with no modification.
For example: an Orders View might include an OrdersDetail partial view. That partial view could be replaced with the OrderDetail Edit View that is also available elsewhere within the application.
Separating the Model from the View makes unit testing more effective and less cumbersome by splitting the code from the context of the presentation layer. You don't want to have to reference System.Web to unit test code that fetches data from a database.
MVC does away with events because events for the most part are just an unnecessary layer between what the client is trying to tell the server to do and the server actually doing it.
In the paging example for webforms the client clicks the button, the browser sends the event/viewstate, and the engine fires the ButtonClicked event. You examine the event, determine the client is intending to page, and you execute the paging logic.
In the MVC paradigm the user clicks a button that makes a request directly to the code that executes the paging logic. Since you know what action the button is supposed to invoke when you put it there why go through all machinations of the event firing? In your controller you certainly could fire an event when you get the command but I honestly can't imagine the use case for doing so.
Both methods accomplish the same thing but MVC just removes a layer of complexity.

When "must" I use asp.net CreateChildControls()?

While it seems that the "right" way to make a server control is to construct all child controls inside CreateChildControls call. But since it's difficult to know when it will be called (which is the whole point as a perf optimzation), I see most of our devs construct in OnInit, or OnLoad. And this works 99% of the case.
Are there cases where we have to use CreateChildControls?
You should ALWAYS construct your child controls in CreateChildControls. This is the proper time in the Lifecycle to initialize and add them to the control tree. One of the reasons for this is that many times the method EnsureChildContols is called, which then calls CreateChildControls if necessary. Best Practice, just do it.
Read Control Execution Lifecycle
The CreateChildControls method is called whenever the ASP.NET page framework needs to create the controls tree and this method call is not limited to a specific phase in a control's lifecycle. For example, CreateChildControls can be invoked when loading a page, during data binding, or during rendering.
Performance-wise, waiting to create a child control will save your server some unnecessary CPU time. For example, if an exception is raised or the thread is aborted prior to CreateChildControls() being called, the clock cycles necessary to create those controls are saved.
What's your reasoning for saying that creating controls in OnInit is more performant than during CreateChildControls()?
You will get away with creating your controls in Init or Load until you write a control that needs to recreate the controls.
I find it is always best to create the controls in CreateChildControls and then use EnsureChildControls to control ensure they are created when you need them. This allows you the ability to tear down the controls by setting ChildControlsCreated to false and have them recreated again when needed.

Dynamically added controls in Asp.Net

I'm trying to wrap my head around asp.net. I have a background as a long time php developer, but I'm now facing the task of learning asp.net and I'm having some trouble with it. It might very well be because I'm trying to force the framework into something it is not intended for - so I'd like to learn how to do it "the right way". :-)
My problem is how to add controls to a page programmatically at runtime. As far as I can figure out you need to create the controls at page_init as they otherwise disappears at the next PostBack. But many times I'm facing the problem that I don't know which controls to add in page_init as it is dependent on values from at previous PostBack.
A simple scenario could be a form with a dropdown control added in the designer. The dropdown is set to AutoPostBack. When the PostBack occur I need to render one or more controls denepending on the selected value from the dropdown control and preferably have those controls act as if they had been added by the design (as in "when posted back, behave "properly").
Am I going down the wrong path here?
I agree with the other points made here "If you can get out of creating controls dynamically, then do so..." (by #Jesper Blad Jenson aka) but here is a trick I worked out with dynamically created controls in the past.
The problem becomes chicken and the egg. You need your ViewState to create the control tree and you need your control tree created to get at your ViewState. Well, that's almost correct. There is a way to get at your ViewState values just before the rest of the tree is populated. That is by overriding LoadViewState(...) and SaveViewState(...).
In SaveViewState store the control you wish to create:
protected override object SaveViewState()
{
object[] myState = new object[2];
myState[0] = base.SaveViewState();
myState[1] = controlPickerDropDown.SelectedValue;
return myState
}
When the framework calls your "LoadViewState" override you'll get back the exact object you returned from "SaveViewState":
protected override void LoadViewState(object savedState)
{
object[] myState = (object[])savedState;
// Here is the trick, use the value you saved here to create your control tree.
CreateControlBasedOnDropDownValue(myState[1]);
// Call the base method to ensure everything works correctly.
base.LoadViewState(myState[0]);
}
I've used this successfully to create ASP.Net pages where a DataSet was serialised to the ViewState to store changes to an entire grid of data allowing the user to make multiple edits with PostBacks and finally commit all their changes in a single "Save" operation.
You must add your control inside OnInit event and viewstate will be preserved. Don't use if(ispostback), because controls must be added every time, event in postback!
(De)Serialization of viewstate happens after OnInit and before OnLoad, so your viewstate persistence provider will see dynamically added controls if they are added in OnInit.
But in scenario you're describing, probably multiview or simple hide/show (visible property) will be better solution.
It's because in OnInit event, when you must read dropdown and add new controls, viewstate isn't read (deserialized) yet and you don't know what did user choose! (you can do request.form(), but that feels kinda wrong)
After having wrestled with this problem for at while I have come up with these groundrules which seems to work, but YMMV.
Use declarative controls whenever possible
Use databinding where possible
Understand how ViewState works
The Visibilty property can go a long way
If you must use add controls in an event handler use Aydsman's tip and recreate the controls in an overridden LoadViewState.
TRULY Understanding ViewState is a must-read.
Understanding Dynamic Controls By Example shows some techniques on how to use databinding instead of dynamic controls.
TRULY Understanding Dynamic Controls also clarifies techniques which can be used to avoid dynamic controls.
Hope this helps others with same problems.
If you truly need to use dynamic controls, the following should work:
In OnInit, recreate the exact same control hierarchy that was on the page when the previous request was fulfilled. (If this isn't the initial request, of course)
After OnInit, the framework will load the viewstate from the previous request and all your controls should be in a stable state now.
In OnLoad, remove the controls that are not required and add the necessary ones. You will also have to somehow save the current control tree at this point, to be used in the first step during the following request. You could use a session variable that dictates how the dynamic control tree was created. I even stored the whole Controls collection in the session once (put aside your pitchforks, it was just for a demo).
Re-adding the "stale" controls that you will not need and will be removed at OnLoad anyway seems a bit quirky, but Asp.Net was not really designed with dynamic control creation in mind. If the exact same control hierarchy is not preserved during viewstate loading, all kinds of hard-to find bugs begin lurking in the page, because states of older controls are loaded into newly added ones.
Read up on Asp.Net page life cycle and especially on how the viewstate works and it will become clear.
Edit: This is a very good article about how viewstate behaves and what you should consider while dealing with dynamic controls: <Link>
Well. If you can get out of creating controls dynamicly, then do so - otherwise, what i whould do is to use Page_Load instead of Page_Init, but instead of placing stuff inside the If Not IsPostBack, then set i just directly in the method.
Ah, that's the problem with the leaky abstraction of ASP.NET web forms.
Maybe you'll be interested to look at ASP.NET MVC, which was used for the creation of this stackoverflow.com web site? That should be an easier fit for you, coming from a PHP (thus, pedal-to-the-metal when it comes to HTML and Javascript) background.
I think the answer here is in the MultiView control, so that for example the dropdown switches between different views in the multi-view.
You can probably even data-bind the current view property of the multiview to the value of the dropdown!
The only correct answer was given by Aydsman. LoadViewState is the only place to add dynamic controls where their viewstate values will be restored when recreated and you can access the viewstate in order to determine which controls to add.
I ran across this in the book "Pro ASP.NET 3.5 in C# 2008" under the section Dynamic Control Creation:
If you need to re-create a control multiple times, you should perform the control creation in the Page.Load event handler. This has the additional benefit of allowing you to use view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the Page.Load event, ASP.NET will apply any view state information that it has after the Page.Load event handler ends. This process is automatic.
I have not tested this, but you might look into it.

Resources