12. webforms: web-based guis in.net. 2 visual studio.net objectives “drag-and-drop gui...

49
12. WebForms: Web-based GUIs in .NET

Upload: leslie-garrett

Post on 24-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

12. WebForms: Web-based GUIs in .NET

2Visual 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

3Visual Studio.NET

Part 1

• ASP.NET architecture…

4Visual Studio.NET

Web serverIIS

ISAPI ExtensionManager

ASPNET_ISAPI.DLLASP.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.EXEASP.NET worker process

CLR

ASP.NET

5Visual 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.EXEASP.NET worker process

CLR

AppDomain

ASP.NETBrowser

http://server/AAAPainting/default.aspx

HTTP Request

AppDomain

ASP.NETBrowser

http://server/BooksForYou/default.aspx

HTTP Request

6Visual Studio.NET

Multi-threaded

• Each AppDomain is multi-threaded, to handle multiple clients

ASPNET_WP.EXEASP.NET worker process

CLR

AppDomain

ASP.NET

Browser http://server/AAAPainting/default.aspx

AppDomain

ASP.NET

Browser

.

.

.

Browser

http://server/AAAPainting/default.aspx

http://server/AAAPainting/default.aspx

7Visual Studio.NET

Part 2

• WebForms…

8Visual 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>

9Visual 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)

10Visual 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 classobject

11Visual 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

12Visual Studio.NET

Example

• A simple WebForms app to view attendee info from DB

13Visual 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

14Visual 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

15Visual 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

16Visual Studio.NET

(4) Design WebForm

• Just like a WinForm

– drag-and-drop from toolbox…

17Visual 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

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

{ … }

{

19Visual 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;

}

20Visual 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

21Visual 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

22Visual 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 1st request

ASPNET_WP.EXEASP.NET worker process

CLR

AppDomain

ASP.NETBrowserhttp://server/AAAPainting/default.aspx

our DLL

23Visual 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…

24Visual 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…

25Visual 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

}

26Visual 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.

27Visual 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

Create

connection

open, read, c

lose

set displa

y values

28Visual Studio.NET

Part 3

• ASP.NET programming model…

29Visual 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

30Visual 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

31Visual 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; }

. . .

32Visual 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}

33Visual 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!");}

34Visual 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 processing4. HTML rendering of page

ASP.NETengine

35Visual Studio.NET

Example

• Every button click is a trip to the server

– watch IE's status bar along the bottom…

36Visual 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 processing4. HTML rendering of page

ASP.NETengine

37Visual 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"

38Visual Studio.NET

Example 1

• We need to clear error message labels!

private void Page_Load(...){ this.lblErrorMsg.set_Text(" "); // clear prev msg . . .

39Visual 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 .

40Visual 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)

41Visual 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);}

42Visual 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

43Visual 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.EXEASP.NET worker process

CLR

AppDomain

ASP.NETBrowserhttp://server/AAAPainting/default.aspx

DLLstatic int i;

44Visual 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)

45Visual 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)) }

46Visual 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 . . .

47Visual 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

48Visual 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…

49Visual 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/