Title: 12. WebForms: Web-based GUIs in .NET
112. WebForms Web-based GUIs in .NET
2Objectives
- Drag-and-drop GUI construction has long been the
norm for Windows development. With the arrival
of ASP.NET and Visual Studio .NET, the same is
now true for web pages with your choice of .NET
language" - ASP.NET architecture
- WebForms
- ASP.NET programming model
3Part 1
4ASP.NET
- ASP.NET is the web-based component of .NET
- ASP.NET is a plug-in for Microsoft's web server
IIS - IIS recognizes extension routes to ASP.NET for
processing - plug-ins also available for Apache, others (?)
http//server/page.aspx
Web server
ASPNET_WP.EXE ASP.NET worker process
Browser
CLR
ISAPI Extension Manager
ASPNET_ISAPI.DLL ASP.NET ISAPI extension
HTTP Request
ASP.NET
IIS
5AppDomains
- Each web app (virtual directory) runs in a
separate domain - An AppDomain is a protection boundary, similar to
a process - this way web apps are isolated from each other
ASPNET_WP.EXE ASP.NET worker process
http//server/AAAPainting/default.aspx
CLR
AppDomain
Browser
ASP.NET
HTTP Request
http//server/BooksForYou/default.aspx
Browser
AppDomain
HTTP Request
ASP.NET
6Multi-threaded
- Each AppDomain is multi-threaded, to handle
multiple clients
Browser
http//server/AAAPainting/default.aspx
ASPNET_WP.EXE ASP.NET worker process
CLR
AppDomain
http//server/AAAPainting/default.aspx
Browser
ASP.NET
. . .
http//server/AAAPainting/default.aspx
AppDomain
ASP.NET
Browser
7Part 2
8Traditional form-based web apps
- HTML already supports the creation of form-based
apps
ltHTMLgt ltHEADgt lttitlegtLoginlt/titlegt lt/HEADgt
ltBODYgt lth2gtPlease loginlt/h2gt ltform
method"get" action"Main.htm" id"Login"gt
Username ltINPUT type"text" id"Name"gt ltBRgt
Password ltINPUT type"text" id"pwd"gt ltBRgt
ltBRgt ltINPUT type"submit" value"Login"gt
lt/formgt lt/BODYgt lt/HTMLgt
9WebForms
- Web-based, form-based .NET apps
- Based on many technologies
- IIS
- ASP.NET (extension to IIS)
- .NET Framework SDK (CLR, FCL, tools)
- Visual Studio .NET (drag-and-drop creation)
10Abstraction
- Like WinForms, WebForms are based on classes in
FCL - separates WebForm app from underlying platform
instance of FCL class
System.Web.UI.Page
CLR
Windows OS
11Creating a WebForm app
- Good news much like creating a WinForm app!
- create appropriate project in Visual Studio
- design form(s) via drag-and-drop of controls
- program events
- run and test
12Example
- A simple WebForms app to view attendee info from
DB
13(1) Create ASP.NET Web App project
- Location name of web site "http//localhost/At
tendeeApp" - virtual directory AttendeeApp
- physical directory C\Inetpub\wwwroot\AttendeeApp
14(2) Project layout
- VS .NET configures IIS for you
- VS .NET creates web site for you
- contains 1 form-based web page
- named WebForm1.aspx by default
- web.config allows you to config things
- e.g. debugging
15(3) Install application support files
- Manually install needed support files into web
app's directory - in this case "C\Inetpub\wwwroot\AttendeeApp"
- component DLLs?
- databases?
- Example
- copy "Attendees.mdb" into root dir
- any custom DLLs in \bin sub-directory
16(4) Design WebForm
- Just like a WinForm
- drag-and-drop from toolbox
17Web controls vs. HTML controls
- Toolbox contains 2 types of controls
- those under Web Forms
- those under HTML
- Both generate pure HTML on client
- though sometimes with JavaScript!
- Web controls
- work like WinForm counterparts
- HTML controls
- mimic standard HTML controls
18(5) Implement events
- WebForms are event-driven, as you would expect
- standard "code-behind" programming with J, C,
VB.NET, - on Page_Load, fill list box from database
- on Button1_Click, display info about selected
attendee
public class WebForm1 extends System.Web.UI.Page
private void Page_Load( ...)
private void Button1_Click ()
19Connection String
- Connection String will be used throughout
- Have program ask where the data is located
import System.Data. import System.Data.OleDb.
. . . String get_sConnection() String
filename "Attendees.mdb" // DB filename
String sConnection null // Find the base
directory in which the application is running
String homeDir System.AppDomain.get_CurrentDomai
n().get_BaseDirectory() sConnection
String.Format("ProviderMicrosoft.Jet.OLEDB.4.0Da
ta Source01",
homeDir, filename) //System.Diagnostics.Deb
ug.WriteLine(this.sConnection) // for debugging
return sConnection
20Page_Load (part 1)
- Use try-catch to handle errors
private void Page_Load(Object sender,
System.EventArgs e) String sql, fn, ln,
name, id IDbConnection dbConn null
try // code to connect to database
and do read (see next slide) //try
catch(Exception ex)
this.lblErrorMsg.set_Text( "Error "
ex.get_Message() ) //catch finally
if ((dbConn ! null)
(dbConn.get_State() ! ConnectionState.Closed))
dbConn.Close()
//finally //load
21Page_Load (part 2)
try dbConn new OleDbConnection(
get_sConnection() ) dbConn.Open()
sql "Select From Attendees Order By
LastName Asc, FirstName Asc" IDbCommand
dbCmd dbCmd new OleDbCommand()
dbCmd.set_CommandText( sql)
dbCmd.set_Connection( dbConn)
IDataReader dbReader dbReader
dbCmd.ExecuteReader() while
(dbReader.Read()) id
String.valueOf(dbReader.get_Item("AID"))
fn String.valueOf(dbReader.get_Item("FirstNa
me")) ln String.valueOf(dbReader.ge
t_Item("LastName")) name ln ", "
fn // have to add an object, not
primitive types this.ListBox1.get_Item
s().Add( new ListItem( name, id)) //try
22(6) Build
- When you build app, Visual Studio builds a DLL
- recall that ASPNET_WP.EXE is the hosting process
- DLL is placed into bin sub-dir of app's IIS
directory - DLL is loaded into AppDomain upon 1st request
ASPNET_WP.EXE ASP.NET worker process
CLR
AppDomain
http//server/AAAPainting/default.aspx
Browser
ASP.NET
our DLL
23(7) Run!
- You can run from within VS
- You can debug from within VS
- How does it work?
- starts up a session of IE
- attaches debugger to IIS
- displays .aspx page marked as "Start Page" in
your project - right-click on .aspx page you want to start with
- select "Set as Start Page"
- NOTE to debug, you need administrative rights
24Client-server relationship
- The server contains lots of code
- see physical directory
- see compiled code in \bin sub-directory
- But the client sees only HTML!
- "View Source" in browser
- wow, how does that work?
- Web controls know how to render themselves in
HTML
25(8) cmdViewInfo_Click (part 1)
- Ensure an item has been selected from List Box
- Note error handling
private void Button1_Click (Object sender,
System.EventArgs e) if (this.ListBox1.get_Se
lectedItem() null) // nothing
selected this.lblErrorMsg.set_Text(
"Please select an attendee!")
return String sql, name, fn, ln,
email String names IDbConnection
dbConn null // DB connection IDbCommand
dbCmd // DB sql command, to use above
connection IDataReader dbReader // DB
reader, with results from above command //
try .. Catch finally block as in the
Page_Load() method
26(8) cmdViewInfo_Click (part 2)
- Retrieve text from Text Box and split into first
and last name - Use this to build sql query string
try // retrieve the Text, not value
part name (String) this.ListBox1.get_Sel
ectedItem().get_Text() char
delimiter' ' names
name.Split(delimiter) // create array of strings
from text ln names0 fn
names1 ln ln.Substring(0,
ln.get_Length() - 1) // remove ',' at end
sql String.Format("Select Email From
Attendees Where FirstName'0' and
LastName'1'",
fn.Replace("'", "''"), ln.Replace("'", "''"))
// System.Diagnostics.Debug.WriteLine("sql
is " sql) // for debugging //
create DB connection from connection string
// //try
1.
2.
27(8) cmdViewInfo_Click (part 3)
try // create DB connection
from connection string dbConn new
OleDbConnection( get_sConnection() )
dbCmd new OleDbCommand() // create DB
command dbCmd.set_CommandText( sql)
// set the sql statement for the command
dbCmd.set_Connection( dbConn) // set the
connection to be used for command
dbConn.Open() // open the DB connection
dbReader dbCmd.ExecuteReader() // read
from DB using command dbReader.Read()
// get a line from DB reader
email String.valueOf(dbReader.get_Item("Email"))
// extract email field
dbReader.Close() // close connections
dbConn.Close() this.TextBox1.set_Text(
fn) // display first name to user
this.TextBox2.set_Text( ln) // display
last name to user this.TextBox3.set_Text(
email) // display email value from
database //try
Create connection
open, read, close
set display values
28Part 3
- ASP.NET programming model
29ASP.NET programming model
- On the surface WebForms appear like WinForms
- But the programming model is different underneath
- due to ASP.NET
- due to client-server paradigm
301 Traditional dialog doesn't work
- For example, these do not work
- MessageBox.Show( )
- form1.Show( )
- Why not?
- think about where form would appear
- Solutions
- if you want to tell user something, display via
label on page - if you want to show another page, redirect browser
31Web-based dialogs
- To display a message to user
private void Button1_Click (...) if
(this.ListBox1.SelectedItem null) //
nothing selected this.lblErrorMsg.Text
"Please select an attendee!" return
. . .
32Web-based exceptions
- Likewise, handle exceptions by displaying
messages
private void Page_Load(...) IDbConnection
dbConn null try // open connection
and access DB, filling list box... . .
. //try catch(Exception ex)
this.lblErrorMsg.set_Text( "Error "
ex.getMessage()) //catch finally
if ((dbConn ! null) (dbConn.get_State() !
ConnectionState.Closed))
dbConn.Close() //finally
33Web-based redirects
- Redirect ASP.NET to a different web page
private void cmdLogin_Click(...) if (ltltvalid
logingtgt) this.get_Response().Redirect("http/
/...") else this.lblErrorMsg.set_Text(
"Login failed!")
342 Event gt round-trip to the server
- There are fewer events to program in WebForms
- primarily Change and Click events only
- Why?
- event code is .NET code, so must be executed by
server - event thus triggers 1 round-trip to server for
processing - an very expensive activity
35Example
- Every button click is a trip to the server
- watch IE's status bar along the bottom
363 Postbacks
- In general, ASP.NET makes a distinction between
- first request by client C for web page X
- subsequent "postbacks" of page X by the same
client C
37Interesting side-effects
- Postback concept leads to interesting
side-effects - each postback creates a new WebForm object
- why? web apps are stateless
- example set breakpoint on Page_Load event
- yet ASP.NET maintains page state for us
- contents of list box, text boxes, etc.
- example view source on client, see
"__ViewState"
38Example 1
- We need to clear error message labels!
private void Page_Load(...)
this.lblErrorMsg.set_Text(" ") // clear prev
msg . . .
39Example 2
- List box is growing and growing with duplicates!
- click button a few times, look at contents of
list box - Solution?
- either load list box the first time only, or
- clear and reload list box every time
private void Page_Load(...)
this.lblErrorMsg.set_Text(" ") if
(this.get_IsPostBack() ) // list box already
loaded! return . . // first request,
load list box from DB .
404 AutoPostBack
- Some events aren't posted right away
- event is "queued" until page is eventually posted
back - example
- list box doesn't postback when you click on an
item - instead, SelectedIndexChanged event is queued
- to witness, code event to display msg in custom
label - notice that multiple clicks on list box yield one
event - To force immediate postback?
- set control's AutoPostBack property to true (if
it has one)
41Example
- Set ListBox's AutoPostBack property to True
- Code SelectedIndexChanged event to display
attendee's info - Note cleaner solution is to route event directly
to Button1_Click() - click on list box in design mode
- view properties
- click yellow lightning bolt icon to see events
- click on drop-down for SelectedIndexChanged
event - select Button1_Click
private void ListBox1_SelectedIndexChanged(object
sender,
System.EventArgs e) // view attendee's
info by executing button click code
this.Button1_Click(sender, e)
425 Statelessness
- Web apps are stateless, kind of
- Each page request is a self-contained operation
- connection is opened
- request is posted
- result is returned
- connection is closed
43Implications
- Implications?
- new WebForm object every time, so objects don't
have state - however, UI object state is maintained for us
by ASP.NET - static fields in our code still work for duration
of AppDomain
ASPNET_WP.EXE ASP.NET worker process
CLR
AppDomain
http//server/AAAPainting/default.aspx
Browser
ASP.NET
DLL static int i
44Solutions?
- Don't try to maintain state, recreate each time
- Use a database
- Ask ASP.NET to do it for you
- will maintain session state for you (state per
client) - will maintain application state for you (global
state)
45Example session state
- Example
- for each client, maintain Attendee objects in a
hash table - Change this.get_Session() to this.get_Application(
) if you want to store Application state rather
than Session state.
private void Page_Load(...) if
(this.get_IsPostBack() ) return Hashtable
attendees new Hashtable() // create table
this.get_Session().Add( "attendees", attendees)
// save ref to table while
(dbReader.Read()) . . .
attendeesname new Attendee(id, name, email)
this.ListBox1.get_Items().Add( new
ListItem( name, id))
46Example (cont'd)
- When state is needed, just pull it out of
ASP.NET's cache
private void ListBox1_SelectedIndexChanged(...)
Hashtable attendees Attendee a
name (String) this.ListBox1.get_SelectedItem().g
et_Text() attendees (Hashtable)
this.get_Session().get_Item ("attendees") //
then extract attendee that matches with name
. . .
47Caveats for stateful apps
- Web apps are stateless for a reason
- Caveats to a stateful design
- too much state will overload server
- state should be recoverable in case of
network/server crash - ASP.NET will keep state in a database if you ask
it to via web.config file - web farms (n gt 1 servers) require special
handling - need to config ASP.NET via web.config file
48Summary
- ASP.NET and WebForms are a huge improvement
- compiled, type-checked languages (no more
scripting) - drag-and-drop page creation (no more HTML
programming) - full power of FCL available with IntelliSense
- But it is a different programming model
- yet another adjustment you have to make
49References
- Books
- J. Sharp et al., Visual J.NET
- F. Onion, "Essential ASP.NET" (both C and VB
editions) - D. Sussman et al., "Beginning ASP.NET 1.0 with
C" - B. Gaster et al., "Fast Track ASP.NET" (C
edition) - Web sites
- http//www.asp.net/
- http//www.asp.net/webmatrix/