Transcript Slide 1

Web Forms
Andy Scrase
.NET developer,
Christchurch NZ
[email protected]
1
Objectives
• Introduce Web Forms
– Control-based programming model
• Present server side controls
– Html controls
– Web controls
• Discuss tools for building web forms
– Visual Studio .NET
– WebMatrix
2
Control-based programming
• Control-based programming is a familiar paradigm
– Desktop application development libraries have used controlbased 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
3
Conceptual model for control-based programming
Programmatic Elements
Menu
ID="Menu1"
Items[] = {"File", "Help" }
IDs[] = { ID_FILE, ID_ABOUT }
Draw()
Label
ID="lb1"
Text="Name:"
Location=(8,16)
Draw()
TextBox
ID="tb1"
Text=""
Location=(104,16)
Draw()
Button
ID="Button1"
Text="Enter"
Location=(104,48)
Draw()
Visual Rendering
Window.TextOut(...)
Window.TextOut(...)
Window.Rectangle(...)
Window.Rectangle(...)
4
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
5
Conceptual model for web forms applications
Programmatic Elements
Toolbar
ID="tb1"
Items[] = {"File", "Help" }
Render()
Label
ID="lb1"
Text="Name:"
Render()
Visual Rendering
<tbns:ToolBar ...>
<span>Name:</span>
TextBox
ID="tb1"
Text=""
Render()
Button
ID="Button1"
Text="Enter"
Render()
<input type=text/>
<input type=submit
value='Enter'/>
6
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 Pagederived class definition
7
An ASP.NET page using server-side controls
<%@ Page Language="C#" %>
<html>
<body>
<form runat="server" >
Enter name: <input type="text" id="_name" runat="server" />
<br/>
Personality: <select id="_personality" runat="server" >
<option>extraverted</option>
<option>introverted</option>
<option>in-between</option>
</select>
<input type="submit" value="Submit" />
<p>
<% if (IsPostBack) {%>
%>
Hi <%=_name.Value%>,
<%
%> you selected
<%=_personality.Value%>
<%
%>
<% } %>
</p>
</form>
</body>
</html>
8
Generated Page-derived class with server-side controls
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
public class WebFormPage1_aspx : Page
{
protected HtmlInputText _name;
protected ListItem
__control3;
protected ListItem
__control4;
protected ListItem
__control5;
protected HtmlSelect
_personality;
protected HtmlForm
__control2;
// ...
}
9
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
10
WebForm Client Interaction
Server
page1_aspx instance #1
_name.Value
_personality.Value
submit request
Client
GET /test/page1.aspx HTTP/1.1
""
""
renders
HTTP/1.1 200 OK
response returned
... <html> ...
<input id="_name" type="text" />
client interaction
page1_aspx instance #2
submit request
"Sam"
_name.Value
_personality.Value "introverted"
submit pressed
POST /test/page1.aspx HTTP/1.1
...
_name=Sam&_personality=introverted
renders
HTTP/1.1 200 OK
... <html> ...
response returned
<input id="_name" type="text"
value="Sam" />
...
11
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
12
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
13
Hierarchy of HtmlControls and the tags they map to
System.Object
System.Web.UI.Control
HtmlControl
HtmlImage <img>
HtmlContainerControl
HtmlForm
HtmlInputControl
HtmlInputFile
<input type=file>
HtmlGenericControl
<form>
<span>,
<div>, ...
HtmlInputHidden
<input type=hidden>
HtmlSelect
<select>
HtmlInputImage
<input type=image>
HtmlTable
<table>
HtmlInputRadioButton <input type=radio>
HtmlInputText
HtmlInputButton
HtmlInputCheckBox
<input type=text>
<input type=button>
<input
type=checkbox>
HtmlTableCell
<td>,<th>
HtmlTableRow
<tr>
HtmlTextArea
<textarea>
HtmlAnchor
<a>
HtmlButton
<button>
14
A sample ASP.NET page written with HtmlControls
<%@ Page Language="C#" %>
<html>
<body>
<form runat="server">
<input type="radio" runat="server">click me</input><br/>
<input type="checkbox" runat="server">check me</input><br/>
<input type="button" value="Push me" runat="server" /><br/>
<input type="text" value="type in me" runat="server" /><br/>
<table runat="server">
<tr><td>cell00</td><td>cell01</td></tr>
<tr><td>cell10</td><td>cell11</td></tr>
</table>
</form>
</body>
</html>
15
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
16
Hierarchy of WebControls
System.Object
System.Web.UI.Control
Repeater
Xml
WebControl
AdRotator
LinkButton
Image
BaseDataList
ListControl
ImageButton
DataGrid
DataList
Button
Calendar
CheckBox
RadioButton
HyperLink
TextBox
RadioButtonList
CheckBoxList
DropDownList
ListBox
Panel
Table
TableCell
TableHeaderCell
TableRow
Label
BaseValidator
BaseCompareValidator
CompareValidator
RangeValidator
CustomValidator
RegularExpressionValidator
RequiredFieldValidator
ValidationSummary
17
A sample ASP.NET page written with WebControls
<%@ Page Language="C#" %>
<html>
<body>
<form runat="server">
<asp:RadioButton Text="click me" runat="server" /><br/>
<asp:CheckBox Text="check me" runat="server" /><br/>
<asp:Button Text="Push me" runat="server" /><br/>
<asp:TextBox Text="type in me" runat="server" /><br/>
<asp:TextBox TextMode="MultiLine" rows="3"
Text="type more in me" runat="server" /><br/>
<asp:Table runat="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>
18
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
19
Events in the Page class
public class Page : TemplateControl, IHttpHandler
{
// Events
public event EventHandler Init;
public event EventHandler Load;
public event EventHandler PreRender;
public event EventHandler Unload;
// Pre-defined event handlers
protected virtual void OnInit(EventArgs e);
protected virtual void OnLoad(EventArgs e);
protected virtual void OnPreRender(EventArgs e);
protected virtual void OnUnload(EventArgs e);
}
20
Example: Adding event handlers using virtual function overriding and manual delegate subscription
public class EventsPage : Page
{
// Override OnInit virtual function to manually
// subscribe a delegate to the Load event
protected override void OnInit(EventArgs e)
{
this.Load += new EventHandler(MyLoadHandler);
base.OnInit(e);
}
// Load event handler
protected void MyLoadHandler(object src, EventArgs e)
{
Response.Write("<tiny>rendered at top of page</tiny>");
}
}
21
Example: Adding event handlers using AutoEventWireup
defaults to true
<!-- AutoEventWireup.aspx -->
<%@ Page Language='C#' AutoEventWireup='true' %>
<script runat="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>
22
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
23
Sample Page Initializing Control State In OnLoad
<%@ Page Language="C#" %>
<script runat="server">
protected override void 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"));
}
else
_message.Text = string.Format("You selected {0}",
_lb.SelectedItem.Text);
base.OnLoad(e);
}
</script>
<html> <body>
<form runat=server>
<asp:ListBox id="_lb" runat="server" /><br>
<asp:Label id="_message" runat="server" /><br>
<input type=submit value="Submit" />
</form></body></html>
24
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
25
Server-side event handler using explicit delegate subscription
<%@ Page Language="C#" %>
<html>
<script runat="server">
protected void OnClickMyButton(object src, EventArgs e)
{
_message.Text = "You clicked the button!";
}
protected override void OnInit(EventArgs e)
{
_MyButton.Click += new EventHandler(OnClickMyButton);
base.OnInit(e);
}
</script>
<body>
<form runat="server">
<h2>ASP.NET event page</h2>
<p>
<asp:Button id="_MyButton" Text="Click me!" runat="server" />
</p>
<asp:Label id="_message" runat="server" />
</form>
</body>
</html>
26
Server-side event handler using OnEvent syntax
<%@ Page Language="C#" %>
<html>
<script runat="server">
protected void OnClickMyButton(object src, EventArgs e)
{
_message.InnerText = "You clicked the button!";
}
</script>
<body>
<form runat="server">
<h2>ASP.NET event page</h2>
<p>
<input type="button" id="_MyButton"
value="Click me!"
OnServerClick="OnClickMyButton" runat="server" />
</p>
<span id="_message" runat="server" />
</form>
</body>
</html>
27
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
28
Server-side event with control state interaction
<%@ Page Language="C#" %>
<script runat="server">
protected override void 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>
<form runat=server>
<asp:ListBox id="_lb" runat="server" /><br>
<asp:Label id="_message" runat="server" /><br>
<input type="button" value="Enter" OnServerClick="OnEnter" />
</form></body></html>
29
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?
• ...
30
Page POST-back event sequence
POST Request issued by client
Page-derived class is created,
constructor is invoked
Server-side control events are fired
IHttpHandler.ProcessRequest method of
Page class invoked
PreRender event of Page class fires
Init event of Page class fires
virtual Render method of Page class invoked
virtual CreateChildControls method of
Page is invoked
virtual RenderChildren method of
Page class invoked
Server-side control state is restored from POST
variables and VIEWSTATE
HTTP Response issued to client
Load event of Page class fires
Unload event of Page class fires
instance of Page-derived class is discarded
31
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
32
Page with server-side controls using code-behind
<%@ Page
Page Language="C#"
Language="C#" Inherits="Page2"
Inherits="Page2"
<%@
Src="Page2.cs" AutoEventWireUp="false"
AutoEventWireUp="false" %>
%>
Src="Page2.cs"
<html>
<body>
<form runat="server">
<h3>Enter name:
<asp:TextBox id="_name" runat="server"/></h3>
<h3>Personality:
<asp:DropDownList id="_personality" runat="server" /></h3>
<asp:Button id="_enterButton" Text="Enter" runat="server"/>
<asp:Label runat="server" id="_message" />
</form>
</body>
</html>
33
Code-behind file for server-side control page
public class
{
protected
protected
protected
protected
Page2 : Page
HtmlSelect
HtmlInputText
HtmlInputButton
HtmlGenericControl
_personality;
_name;
_enterButton;
_messageParagraph;
override protected void OnInit(EventArgs e)
{ _enterButton.ServerClick += new EventHandler(OnEnter); }
override protected void OnLoad(EventArgs e)
{
if (!IsPostBack)
{
_personality.Items.Add(new ListItem("extraverted"));
_personality.Items.Add(new ListItem("introverted"));
_personality.Items.Add(new ListItem("in-between"));
}
}
protected void OnEnter(object src, EventArgs e)
{
string msg = string.Format("Hi {0}, you selected {1}",
_name.Value, _personality.Value);
_messageParagraph.InnerText = msg;
}
}
34
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
35
Web Form Generation
Codebehind attribute used by VS.NET to associate
code-behind file with .aspx file (not equivalent to src=)
36
Code-behind for VS.NET WebForm
namespace WebFormsApp {
public class WebForm1 : Page {
protected Button _PushMe;
protected TextBox _Name;
private void Page_Load(object sender, EventArgs e)
{
// Put user code to initialize the page here
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
_PushMe.Click += new System.EventHandler(Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Button1_Click(object sender, EventArgs e)
{
}
}
}
Server-control
member variables
Load event handler
OnInit override
with call to
InitializeComponent
Explicit event
wire-up
37
WebMatrix
• Free ASP.NET development tool from Microsoft
– Hosts its own web server (can build and test without IIS)
– Many shared features with VS.NET
• Page designer, wizards, syntax highlighting, ...
– What's missing
• Intellisense, Project creation, code-behind support, ...
Download from:
http://www.asp.net/webmatrix
38
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
39