12. WebForms: Web-based GUIs in .NET

acceptableseashoreΑσφάλεια

5 Νοε 2013 (πριν από 3 χρόνια και 9 μήνες)

55 εμφανίσεις


12. WebForms: Web
-
based


GUIs in .NET

2

Visual Studio.NET

Objectives

“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

3

Visual Studio.NET

Part 1


ASP.NET architecture…

4

Visual Studio.NET

Web server

IIS

ISAPI Extension

Manager

ASPNET_ISAPI.DLL

ASP.NET ISAPI extension

ASP.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 (?)

Browser

http://server/page.
aspx

HTTP Request

ASPNET_WP.EXE

ASP.NET worker process

CLR

ASP.NET

5

Visual Studio.NET

AppDomains


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

CLR

AppDomain

ASP.NET

Browser

http://server/
AAAPainting
/default.aspx

HTTP Request

AppDomain

ASP.NET

Browser

http://server/
BooksForYou
/default.aspx

HTTP Request

6

Visual Studio.NET

Multi
-
threaded


Each AppDomain is multi
-
threaded, to handle multiple clients

ASPNET_WP.EXE

ASP.NET worker process

CLR

AppDomain

ASP.NET

Browser

AppDomain

ASP.NET

Browser

.

.

.

Browser

http://server/AAAPainting/default.aspx

7

Visual Studio.NET

Part 2


WebForms…

8

Visual Studio.NET

Traditional form
-
based web apps


HTML already supports the

creation of form
-
based apps

<HTML>


<HEAD>


<title>Login</title>


</HEAD>



<BODY>


<h2>Please login:</h2>


<form method="get" action="Main.htm" id="Login">


Username: <INPUT type="text" id="Name"> <BR>


Password: <INPUT type="text" id="pwd"> <BR> <BR>


<INPUT type="submit" value="Login">


</form>


</BODY>

</HTML>

9

Visual Studio.NET

WebForms


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)

10

Visual Studio.NET

Abstraction


Like WinForms, WebForms are based on classes in FCL


separates WebForm app from underlying platform

System.Web.UI.Page

CLR

Windows OS

instance of

FCL class

object

11

Visual Studio.NET

Creating a WebForm app


Good news: much like creating a WinForm app!

1.
create appropriate project in Visual Studio

2.
design form(s) via drag
-
and
-
drop of controls

3.
program events

4.
run and test


12

Visual Studio.NET

Example


A simple
WebForms
app to view
attendee
info from DB

13

Visual Studio.NET

(1) Create ASP.NET Web App project


Location = name of web site = "
http://localhost/AttendeeApp
"


virtual directory:

AttendeeApp


physical directory:

C:
\
Inetpub
\
wwwroot
\
AttendeeApp

14

Visual Studio.NET

(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

Visual Studio.NET

(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

Visual Studio.NET

(4) Design WebForm


Just like a WinForm


drag
-
and
-
drop from toolbox…

17

Visual Studio.NET

Web 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

Visual Studio.NET

(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 (…)


{ … }

{

19

Visual Studio.NET

Connection 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_CurrentDomain().get_BaseDirectory();


sConnection = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}{1}",


homeDir, filename);


//System.Diagnostics.Debug.WriteLine(this.sConnection);

// for debugging


return sConnection;

}

20

Visual Studio.NET

Page_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

21

Visual Studio.NET

Page_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("FirstName"));


ln = String.valueOf(dbReader.get_Item("LastName"));


name = ln + ", " + fn;


// have to add an object, not primitive types


this.ListBox1.get_Items().Add( new ListItem( name, id)); }

}//try

22

Visual Studio.NET

(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 1
st

request

ASPNET_WP.EXE

ASP.NET worker process

CLR

AppDomain

ASP.NET

Browser

http://server/AAAPainting/default.aspx

our DLL

23

Visual Studio.NET

(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…

24

Visual Studio.NET

Client
-
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

Visual Studio.NET

(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_SelectedItem() == 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

Visual Studio.NET

(8) cmdViewInfo_Click (part 2)

1.
Retrieve text from Text Box and split into first and last name

2.
Use this to build
sql

query string


try {


// retrieve the Text, not value part


name = (String) this.ListBox1.get_SelectedItem().get_Text();




char delimiter[]={' '};


names = name.Split(delimiter);

// create array of strings from text


ln = names[0];


fn = names[1];


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

Visual Studio.NET

(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

28

Visual Studio.NET

Part 3


ASP.NET programming model…


29

Visual Studio.NET

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

30

Visual Studio.NET

#1: 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

31

Visual Studio.NET

Web
-
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;


}



.


.


.


32

Visual Studio.NET

Web
-
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

}

33

Visual Studio.NET

Web
-
based redirects


Redirect ASP.NET to a different web page…


private void cmdLogin_Click(...)

{


if (
<<valid login>>
)


this.get_Response().Redirect("
http://...
");


else


this.lblErrorMsg.set_Text(

"Login failed!");

}

34

Visual Studio.NET

#2: Event ==> 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…

IIS

client

1. initial request is posted

2. HTML rendering of page

3. same page is "posted
-

back" for event processing

4. HTML rendering of page

ASP.NET

engine

35

Visual Studio.NET

Example


Every button click is a trip to
the server


watch IE's status bar along
the bottom…


36

Visual Studio.NET

#3: 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



IIS

client

1. initial request is posted

2. HTML rendering of page

3. same page is "posted
-

back" for event processing

4. HTML rendering of page

ASP.NET

engine

37

Visual Studio.NET

Interesting side
-
effects


Postback concept leads to interesting side
-
effects…

1.
each postback creates a new WebForm object


why? web apps are stateless…


example: set breakpoint on Page_Load event

2.
yet ASP.NET maintains page state for us


contents of list box, text boxes, etc.


example: view source on client, see "__ViewState"



38

Visual Studio.NET

Example 1


We need to clear error message labels!


private void
Page_Load
(...)

{


this.lblErrorMsg.set_Text("

");
// clear prev msg


.


.


.


39

Visual Studio.NET

Example 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


.


40

Visual Studio.NET

#4: 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)

41

Visual Studio.NET

Example


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

}

42

Visual Studio.NET

#5: 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

43

Visual Studio.NET

Implications


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

ASP.NET

Browser

http://server/AAAPainting/default.aspx

DLL

static int i;

44

Visual Studio.NET

Solutions?


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)

45

Visual Studio.NET

Example: 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())


{


.


.


.


attendees[name] = new Attendee(id, name, email);


this.ListBox1.get_Items().Add( new ListItem( name, id))


}

46

Visual Studio.NET

Example (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().get_Text();



attendees = (Hashtable) this.get_Session().get_Item ("attendees");



// then extract attendee that matches with name


.


.


.


47

Visual Studio.NET

Caveats 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 > 1 servers) require special handling


need to config ASP.NET via web.config file


48

Visual Studio.NET

Summary


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…

49

Visual Studio.NET

References


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/