400 likes | 667 Views
Web Forms. Objectives. Introduce Web Forms Control-based programming model Present server side controls Html controls Web controls Discuss tools for building web forms Visual Studio 2005/2008. Control-based programming. Control-based programming is a familiar paradigm
E N D
Objectives • Introduce Web Forms • Control-based programming model • Present server side controls • Html controls • Web controls • Discuss tools for building web forms • Visual Studio 2005/2008
Control-based programming • Control-based programming is a familiar paradigm • Desktop application development libraries have used control-based programming for years • A program consists of a collection of controls • Each control knows how to render its state to the screen • The developer manipulates the state of these controls and lets rendering happen implicitly
Control-based programming for web applications • ASP.NET brings control-based programming to web apps • Server-side objects created to represent elements of a page • Each server-side object capable of rendering itself as HTML • Layered on top of Request/Response architecture of HTTP • Some desktop paradigms work well • Others must be re-thought
Server-side controls • The web forms model is based on a set of primitive controls • Called server-side controls as they exist on the server and provide rendering to the client as HTML • Created using runat=server attribute on traditional HTML elements in a .aspx page • Can be referenced within server-side code using designated ID • Implicitly added as member variables to the generated Page-derived class definition
An ASP.NET page using server-sidecontrols <%@ Page Language="C#" %> <html> <body> <formrunat="server"> Enter name: <inputtype="text"id="_name"runat="server"/> <br/> Personality: <selectid="_personality"runat="server"> <option>extraverted</option> <option>introverted</option> <option>in-between</option> </select> <inputtype="submit"value="Submit"/> <p> <% if (IsPostBack) {%> Hi <%=_name.Value%>, you selected <%=_personality.Value%> <% } %> </p> </form> </body> </html> <%@ Page Language="C#" %> <% %> <% %> <% %> <% %>
Generated Page-derived class with server-sidecontrols using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; publicclass WebFormPage1_aspx : Page { protected HtmlInputText _name; protected ListItem __control3; protected ListItem __control4; protected ListItem __control5; protected HtmlSelect _personality; protected HtmlForm __control2; // ... }
Server-side control state management • Server-side controls must manage their state • Initial GET request to a page creates the server side controls with their default values • Subsequent POST requests back to the same page creates the server side controls with the values in the POST body • Any changes made to the value of the controls during the processing of a request will be reflected when the page is rendered
WebForm Client Interaction Server Client submitrequest page1_aspx instance #1 _name.Value _personality.Value GET /test/page1.aspx HTTP/1.1 "" "" renders HTTP/1.1 200 OK ... <html> ... <input id="_name" type="text" /> response returned client interaction submit pressed page1_aspx instance #2 _name.Value _personality.Value submit request POST /test/page1.aspx HTTP/1.1 ... _name=Sam&_personality=introverted "Sam" "introverted" renders HTTP/1.1 200 OK ... <html> ... <input id="_name" type="text" value="Sam" /> ... response returned
Server Control Behaviors • Server controls retain their state between POST requests back to the same page • No need to re-initialize state on POST-back requests • Can not be used for cross-page POST requests • Controls that are not intrinsically included in a POST request have their state propagated via a hidden field (ViewState) • More on this later
HtmlControls • HtmlControls are server-side representations of standard HTML elements • Any HTML element in an ASPX page marked with the runat=server attribute will become an HTML control on the server • All derive from HtmlControl class • HTML elements with no distinguished server-side functionality (like div, span, etc.) are all represented as HtmlGenericControl instances
A sample ASP.NET page written with HtmlControls <%@ Page Language="C#" %> <html> <body> <formrunat="server"> <inputtype="radio"runat="server">click me</input><br/> <inputtype="checkbox"runat="server">check me</input><br/> <inputtype="button"value="Push me"runat="server"/><br/> <inputtype="text"value="type in me"runat="server"/><br/> <tablerunat="server"> <tr><td>cell00</td><td>cell01</td></tr> <tr><td>cell10</td><td>cell11</td></tr> </table> </form> </body> </html> <%@ Page Language="C#" %>
WebControls • WebControls provide a more consistent object model and a higher level of abstraction than HtmlControls • Most HTML elements can also be represented as WebControls on the server • WebControl versions typically have a more consistent interface (background color is always BackColor property whereas in HTML it may be a style attribute (span) or a property (table) ) • WebControls also provide higher-level controls with more functionality than primitive HTML elements (like the Calendar control) • WebControls may render themselves differently based on client browser capabilities
A sample ASP.NET page written with WebControls <%@ Page Language="C#" %> <html> <body> <formrunat="server"> <asp:RadioButtonText="click me"runat="server" /><br/> <asp:CheckBoxText="check me"runat="server" /><br/> <asp:ButtonText="Push me"runat="server"/><br/> <asp:TextBoxText="type in me"runat="server"/><br/> <asp:TextBoxTextMode="MultiLine"rows="3" Text="type more in me"runat="server"/><br/> <asp:Tablerunat="server"> <asp:TableRow> <asp:TableCell>cell00</asp:TableCell> <asp:TableCell>cell01</asp:TableCell> </asp:TableRow> <asp:TableRow> <asp:TableCell>cell10</asp:TableCell> <asp:TableCell>cell11</asp:TableCell> </asp:TableRow> </asp:Table> </form> </body> </html> <%@ Page Language="C#" %>
Page Lifecycle • Each request to a page results in a new instance of that class • Page state is not retained between requests • Several events defined by the Page class • Useful to define handlers in code-behind classes • 4 events called in sequence during a page's lifetime • Possible to subscribe to these events in three ways • Explicitly subscribing a delegate to the event • Overriding virtual function handlers in base class • Defining functions named Page_xxx with AutoEventWireup set to true
Events in the Page class publicclass Page : TemplateControl, IHttpHandler { // Events publicevent EventHandler Init; publicevent EventHandler Load; publicevent EventHandler PreRender; publicevent EventHandler Unload; // Pre-defined event handlers protectedvirtualvoid OnInit(EventArgs e); protectedvirtualvoid OnLoad(EventArgs e); protectedvirtualvoid OnPreRender(EventArgs e); protectedvirtualvoid OnUnload(EventArgs e); }
Example: Adding event handlers using virtual function overriding and manual delegate subscription publicclass EventsPage : Page{// Override OnInit virtual function to manually// subscribe a delegate to the Load eventprotectedoverridevoid OnInit(EventArgs e) {this.Load += new EventHandler(MyLoadHandler); base.OnInit(e); }// Load event handlerprotectedvoid MyLoadHandler(object src, EventArgs e) { Response.Write("<tiny>rendered at top of page</tiny>"); }}
Example: Adding event handlers using AutoEventWireup defaults to true <!-- AutoEventWireup.aspx --> <%@ Page Language='C#' AutoEventWireup='true' %> <scriptrunat="server"> protected void Page_Load(object src, EventArgs e) { Response.Write("<h4>Load event fired!</h4>"); } </script> <html> <body> <h1>AutoEventWireup Page</h1> </body> </html> <%@ Page Language='C#' AutoEventWireup='true' %>
Server-side control state initialization • The Load event of the Page class is commonly where control state is initialized • Invoked after controls have been created, but before rendering • Because controls retain their state across POST requests, it is usually only necessary to initialize their state once // Common control interaction if (!IsPostBack) initialize control state else look at/process client-submitted state
Sample Page Initializing Control State In OnLoad <%@ Page Language="C#" %> <scriptrunat="server"> protectedoverridevoidOnLoad(EventArgs e) { if (!IsPostBack) { _lb.Items.Add(newListItem("item 1")); _lb.Items.Add(newListItem("item 2")); _lb.Items.Add(newListItem("item 3")); _lb.Items.Add(newListItem("item 4")); } else _message.Text = string.Format("You selected {0}", _lb.SelectedItem.Text); base.OnLoad(e); } </script> <html> <body> <formrunat=server> <asp:ListBoxid="_lb"runat="server"/><br> <asp:Labelid="_message"runat="server"/><br> <inputtype=submitvalue="Submit"/> </form></body></html> <%@ Page Language="C#" %>
Events • Many server-side controls can generate server-side events • Exposed as standard CLR EventHandler delegates • To subscribe to an event of a server-side control • Construct a new instance of the EventHandler delegate • Initialize it with your handler function pointer • Subscribe the delegate to the control's event • Alternatively, you can subscribe to an event by • Indicating your handler function with the OnEvent attribute in the control's tag
Server-sideeventhandlerusing explicit delegatesubscription <%@ Page Language="C#" %> <html> <scriptrunat="server"> protectedvoidOnClickMyButton(objectsrc, EventArgs e) { _message.Text = "You clicked the button!"; } protectedoverridevoidOnInit(EventArgs e) { _MyButton.Click += newEventHandler(OnClickMyButton); base.OnInit(e); } </script> <body> <formrunat="server"> <h2>ASP.NET event page</h2> <p> <asp:Buttonid="_MyButton"Text="Click me!"runat="server"/> </p> <asp:Labelid="_message"runat="server"/> </form> </body> </html> <%@ Page Language="C#" %>
Server-sideeventhandlerusingOnEventsyntax <%@ Page Language="C#" %> <html> <scriptrunat="server"> protectedvoidOnClickMyButton(objectsrc, EventArgs e) { _message.InnerText = "You clicked the button!"; } </script> <body> <formrunat="server"> <h2>ASP.NET event page</h2> <p> <inputtype="button"id="_MyButton" value="Click me!" OnServerClick="OnClickMyButton"runat="server"/> </p> <spanid="_message"runat="server" /> </form> </body> </html> <%@ Page Language="C#" %>
Events in the Page Lifecycle • Events are issued after the Load event, but prior to rendering • Very common control interaction is: • In Load event handler, initialize control state (when IsPostBack is False) • In server-side event handlers for controls (OnButtonClick...), process client-submitted state
Server-sideeventwith control state interaction <%@ Page Language="C#" %> <scriptrunat="server"> protectedoverridevoid OnLoad(EventArgs e) { if (!IsPostBack) { _lb.Items.Add(new ListItem("item 1")); _lb.Items.Add(new ListItem("item 2")); _lb.Items.Add(new ListItem("item 3")); _lb.Items.Add(new ListItem("item 4")); } base.OnLoad(e); } protected void OnEnter(object src, EventArgs e) { _message.Text = string.Format("You selected {0}", _lb.SelectedItem.Text); } </script> <html> <body> <formrunat=server> <asp:ListBoxid="_lb"runat="server"/><br> <asp:Labelid="_message"runat="server"/><br> <inputtype="button"value="Enter" OnServerClick="OnEnter"/> </form></body></html> <%@ Page Language="C#" %>
Page event sequencing • It is critical to understand the event sequencing of the Page • Pages are created and discarded with each request • There is an explicit, deterministic sequences of events that occurs with the lifetime of each page • It is important to know where in that sequence you should perform tasks • When can I look at a control's contents? • When can I modify a control's contents? • When is the Request object available? • ...
Web Forms and Code-behind • Server-side controls in combination with code-behind enables true separation of page logic from page layout and rendering • Server-side controls must be declared in code-behind class as public or protected variables with names matching control IDs • During parsing of the .aspx page, ASP.NET will look for member variables with matching names in the base class • If it finds a variable of the appropriate type, it will use it • Otherwise it will create a new member variable in the .aspx-generated class definition
Page with server-sidecontrolsusing code-behind <%@ Page Language="C#" Inherits="Page2" Src="Page2.cs" AutoEventWireUp="false" %> <html> <body> <formrunat="server"> <h3>Enter name: <asp:TextBoxid="_name"runat="server"/></h3> <h3>Personality: <asp:DropDownListid="_personality"runat="server"/></h3> <asp:Buttonid="_enterButton"Text="Enter"runat="server"/> <asp:Labelrunat="server"id="_message"/> </form> </body> </html> <%@ Page Language="C#" Inherits="Page2" Src="Page2.cs" AutoEventWireUp="false" %>
Code-behind file for server-side control page publicclass Page2 : Page{protectedHtmlSelect _personality;protectedHtmlInputText _name;protectedHtmlInputButton _enterButton;protectedHtmlGenericControl _messageParagraph; overrideprotectedvoidOnInit(EventArgs e) { _enterButton.ServerClick += newEventHandler(OnEnter); } overrideprotectedvoidOnLoad(EventArgs e) {if (!IsPostBack) { _personality.Items.Add(newListItem("extraverted")); _personality.Items.Add(newListItem("introverted")); _personality.Items.Add(newListItem("in-between")); } } protectedvoidOnEnter(objectsrc, EventArgs e) {stringmsg = string.Format("Hi {0}, you selected {1}", _name.Value, _personality.Value); _messageParagraph.InnerText = msg; }}
Web Forms Applications with Visual Studio .NET • Visual Studio .NET supports creating Web projects • Generates new virtual directory for your project • Project output is a single assembly containing all code-behind, deployed in the /bin directory • Designer support for WebForms with automatic code-behind updates • Wizards for standard web components (web forms, user controls, etc.) • Standard ClassLibrary projects can be used to create ASP.NET applications as well
Web Form Generation Codebehind attribute used by VS.NET to associate code-behind file with .aspx file (not equivalent to src=)
Code-behind for VS.NET WebForm namespace WebFormsApp { publicclass WebForm1 : Page { protected Button _PushMe; protected TextBox _Name; privatevoid Page_Load(object sender, EventArgs e) { // Put user code to initialize the page here } #region Web Form Designer generated code overrideprotectedvoid OnInit(EventArgs e) { InitializeComponent(); base.OnInit(e); } privatevoid InitializeComponent() { _PushMe.Click += new System.EventHandler(Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion privatevoid Button1_Click(object sender, EventArgs e) { } } } Server-control member variables Load event handler OnInit override with call to InitializeComponent Explicit event wire-up
Summary • ASP.NET brings control-based programming to web development • Server-side controls retain state between post-backs • HtmlControls provide server-side equivalents of HTML elements • WebControls provide more consistent object model for server-side controls, as well as some more sophisticated controls
For more information, please contact: Uladzimir Tsikhon Software Engineering Manager, Belarus Recourse Development Department EPAM Systems, Inc. Belarus, MinskPhone: +375(17) 2101662 ext 1756 Fax: +375(17) 2101168 Email: uladzimir_tsikhon@epam.com http://www.epam.com