Data-Driven Websites

Download Report

Transcript Data-Driven Websites

Programming
Data-Driven WebSites
(ASPX, Active Server Pages)
Chris North
CS 4604: DB
WinApp vs WebApp
• Standard client application (WinApp)
•
•
•
•
•
•
E.g. C#, Java
Single user, location
Portability is less critical
Power, dynamics
Targeted audience
Distributed executable
• Server-side application (WebApp)
•
•
•
•
•
•
Broad user class
Lightweight, Supports lo-fi clients
One-time users, quick, no installation/updates
Distributed simultaneous users
Simpler functionality, information access
Centralized executable, data
Data-Driven WebSites
Client
(Browser)
URL request
html page
Server
(Web server)
Database
html
Table
• Page = Server-side script
• Dynamically generates page at client request
• Pulls data from DB to create page contents
• E.g. E-Bay, Amazon, …
Sequence
1.
2.
3.
4.
5.
6.
User clicks http://server.com/script.aspx link
Client requests script.aspx from server.com
Server.com executes script.aspx
Script.aspx generates html page (using DB data)
Server.com sends html page to client
Client displays page
Example
Amazon.com server
Books.asp
Cart.asp
Purchase.asp
•Shows books list
•Add to cart
•Displays cart contents
•Delete items
•Charges credit card
•Displays ‘thankyou’
•View cart button
•Purchase button
•Link back to books
ASPX
• Microsoft Active Server Pages, .Net
• IIS server
• Old ASP:
If install IIS after install VStudio .Net, must run:
C:/windows/MS.net/framework/Vx.x/aspnet_regiis.exe -i
• Html with embedded server scripts
• Session support
• Visual Basic script
• ASPX .Net:
•
•
•
•
Separation of html and code
Additional state-preservation capability
C# (or any other lang)
Visual Studio .net, C# Web Application
ASP = html + script
• New server-script tags: <% code %> <%= expression %>
• Tag contents are executed and replaced with script’s output
• Myscript.asp:
<%@ Page language="c#” %>
<html><body>
The time is <%= System.Date.Now.ToString() %>
<% if(System.Date.Now < “12:00pm”){ %>
<p>Good morning
<% }else{ %>
<p>Good afternoon
<% } %>
</body></html>
At page request, Server executes script
• Client receives:
<html><body>
The time is 2:03pm
<p>Good afternoon
</body></html>
<%= expr %> Replaced with value of expr
<% code %>
Executes code
ASPX: Separate code
•
•
•
•
.aspx = html with asp tags
.aspx.cs = associated Csharp code
Also supports ASP-style embedded code
Env. similar to WinApp, execution different
•
Execution order:
1.
2.
3.
4.
Constructor, OnInit (auto-generated code)
Page load
Any events from form submit request
Embedded code in .aspx
Processing Form Input
• POST
(aspx default)
• <form action=“myscript.exe” method=post>
• Myscript.aspx.cs reads input from Control properties
» E.g: ListBox1.SelectedValue
• GET querystring
• <form action=“myscript.exe” method=get>
• http://myserver.com/myscript.aspx?var1=value&…
• Myscript.aspx.cs reads input from Request.QueryString
» E.g: this.Request.QueryString[“var1”]
Problems
• Many simultaneous users
• Who’s who?
• Request-Response HTTP model
(page requests are independent)
• How to maintain contiguous program state?
• UI (browser) disconnect from back-end (server)
• How to keep UI in sync with back-end? (e.g. ‘Back’ button)
…
Books.asp
Cart.asp
Purchase.asp
Different than GUI programming!
• Standard WinApp GUI:
• One user (per executable)
• ‘Global’ state data
• Client = server
– UI and back-end are same executable
Shopping.exe
Books window
Cart window
Purchase window
Solutions in ASPX
• Provides user ‘session’ awareness
• (a) Recognizes users by cookies
• (b) Maintains contiguous state info for each user in global
storage.
» E.g: this.session[“var1”]
• (c) Keeps page state info in a hidden form item.
» Maintains properties of all UI controls
• Automatic
•Who is the user?
•What is his data?
•Where is he in
the ‘application’?
Form Input & Session State
Enter your name:
• Process form input, store state info:
Button1_Click()
this.Session(“myname”) = TextBox1.Text;
chris
Send
• HTML output based on session state:
Label1.Text = “Welcome “ + this.Session(“myname”);
Or:
<html><body>
Welcome, <%= this.Session(“myname”) %>
</body></html>
Welcome, chris
Useful ASPX Objects
• this. properties:
•
•
•
•
•
•
.Session: specific to each user
.Application: global, all users
.Request: .querystring, .form, …
.Response: .redirect, .write, …
.Server: utilities
.IsPostBack
• Global.asax events:
• Session_Start, Session_End
• Application_Start, Application_End
Database Access
• The usual connect & query code:
OleDbConnection con = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:/census4604.mdb"); // Jet=Access
OleDbCommand cmd = new OleDbCommand(
"SELECT * FROM States4604", con); // SQL query
OleDbDataAdapter adpt = new OleDbDataAdapter(cmd);
DataSet data = new DataSet( );
adpt.Fill(data); // execute the query and put result in ‘data’
Database Display
• Binding data to UI controls:
ListBox1.DataSource = data.Tables[0];
ListBox1.DataTextField = "Name";
ListBox1.DataValueField = “ID";
ListBox1.DataBind();
// always do this to make it finalized
DataGrid1.DataSource = data.Tables[0];
DataGrid1.DataBind();
// always do this to make it finalized
• Limited customization capability
• Can get events
• Simple coding, similar to WinApp
Database Display
• Inline scripting:
<table>
<% foreach(DataRow r in data.Tables[0].Rows){ %>
<tr>
<% foreach(Object v in r.ItemArray){ %>
<td> <%= v.ToString( ) %> </td>
<% } %>
</tr>
<% } %>
</table>
• Complete customization, html-level control, more complex code
Database Display
• Repeater control (combines binding & inline)
In file.aspx.cs:
Repeater1.DataSource = data.Tables[0];
Repeater1.DataBind();
In file.aspx:
<asp:repeater id="Repeater1" runat="server">
<HeaderTemplate> <ul> </HeaderTemplate>
<ItemTemplate>
<li> <%# DataBinder.Eval(Container, "DataItem.Name") %> </li>
</ItemTemplate>
<FooterTemplate> </ul> </FooterTemplate>
</asp:repeater>
•
Compromise: some customization, some automation
InfoVis tricks on web pages
• Simple graphics:
Item1
Item2
Item3
Item4
Item5
…
• Image trick: red.gif = 1x1 red pixel gif
• Control the location (dhtml,xhtml):
<img href=“red.gif” STYLE="position:absolute;
left:100px; top:49px; z-index:-1" >
» places the gif at (100,49) on the page
» Z-index -1 means put it behind the page text
• Control the size (html):
<img href=“red.gif” width=75 height=10>
» Stretches it into a 75x100 red rectangle
Open Problems:
Client-Server Out of Sync
• ‘Re-post’ problem:
• E.g: Submit, Back, Submit; purchased twice!
• Solution: give each form unique ID, counter
• ‘Jump in too deep’ problem
• E.g: nav by bookmark deep into app, without logging in.
• On deep page, check for username, redirect to login page
• Test page state against session state.
• Browser cache problem
• E.g: browser shows old page instead of getting new content
• Defeat cache using expiration tags
Defeating Browser Cache
• Expiration tags:
<%
Response.Expires = -1
Response.Expiresabsolute = Now() - 2
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
%>
• Random queryString:
<a href=“myscript.asp?Nocache=<%=rnd()%>” >
<a href=“myscript.asp?Nocache=4857493>”
Consistent look-and-feel
• Banner, Navigation bar, …
• Server-side ‘include’ files:
• Put banner, nav bar in separate ‘include’ file:
• Can be used in .html files too
<!-- #include file = "myfile.asp" -->
Document Object Model
• (more useful in old ASP)
<form name=“myform”>
<input type=“button” name=“mybutton” value=“OK”
onclick=“document.myform.mybutton.color=red”>
</form>
document
myform
mybutton
…
…