[ Home | Syllabus | Course Notes | Assignments | Search]
Application is a grouping of (in a common directory)
.aspx pages
ASCX files containing user controls
assemblies
supporting files (global.asax, web.config)
NOTE: An assembly can consist of multiple DLLs in general (see pages 94-)
Installing and uninstalling an application is simply a matter of creating or destroying the application files
Can even swap to a newer version while transactions are running
ASP.NET applications run inside the aspnet_wp process as shown below
HTTPContext object contains the following properties
Request: query string access, cookies
Response: generates output HTML
Application: associative memory of information relevant to this application
Cache: similar to APPLICATION but with expiration time
Session: State information about the
session connection to a client (identified by a 120bit session id stored in
a cookie OR url STRING)
Can be stored in a session store so can be accessed by a server farm
Error:
User: identity of the client
Handler: Access to low level handlers
Configuration information is stored in the directory instead of the registry (allows simple copies of application to the server -XCOPY). This is an XML file, here is the general structure
<configuration> <appSettings> <!-- appSettings values go here --> </appSettings> <system.web> <!-- ASP.NET configuration settings go here --> </system.web> </configuration>
associative memory of strings that can be used by the application.
Example, consider the following code in a PageLoad event handler for connecting to a database
SqlDataAdapter adapter = new SqlDataAdapter ("select * from titles where price != 0", "server=hawkeye;database=pubs;uid=sa;pwd="); DataSet ds = new DataSet (); adapter.Fill (ds);
Suppose many page load information from the same data base and the data base server information changes. - Would have to edit all web pages - one solution is to put the connection information in the web.config file
<configuration> <appSettings> <add key="MyConnectionString" value="server=hawkeye;database=pubs;uid=sa;pwd=" /> </appSettings> </configuration>
Now the code in the pageLoad handler is
string conn = ConfigurationSettings.AppSettings["MyConnectionString"]; SqlDataAdapter adapter = new SqlDataAdapter ("select * from titles where price != 0", conn); DataSet ds = new DataSet (); adapter.Fill (ds);
Section Name |
Description |
authentication |
Sets the authentication mode and specifies settings for the mode selected |
authorization |
Specifies who is allowed to access resources in this directory and its subdirectories |
browserCaps |
Maps user-agent data to browser capabilities |
clientTarget |
Maps user-agent data to browser types |
compilation |
Specifies run-time compilation settings such as whether executables should be compiled with debug symbols, maps file name extensions and Language attributes to compilers, and identifies the assemblies that ASP.NET links to |
customErrors |
Enables the use of custom error pages and specifies how errors should be reported on clients and servers |
httpRuntime |
Specifies request time-outs and other settings used by the ASP.NET runtime |
globalization |
Specifies character encodings for requests and responses |
httpHandlers |
Maps URLs to HTTP handlers (for example, maps requests for ASPX files to System.Web.UI.PageHandlerFactory) |
httpModules |
Identifies HTTP modules called in response to HTTP requests |
identity |
Controls the identity that ASP.NET assigns to individual requests |
machineKey |
Specifies encryption and validation settings (for example, the key and algorithm used to encrypt authentication cookies) |
pages |
Specifies page-level configuration settings such as whether output buffering, session state, and view state are enabled |
processModel |
Specifies configuration settings for ASP.NET worker processes |
securityPolicy |
Maps trust levels to CONFIG files containing security policies |
sessionState |
Specifies session state settings (for example, where session state is stored) |
trace |
Enables and disables tracing and specifies trace settings |
trust |
Specifies the code access security trust level |
webControls |
Identifies the location on the server of client scripts used by ASP.NET Web controls |
webServices |
Contains Web service settings |
example
<configuration> <system.web> <trace enabled="true" /> </system.web> </configuration>
Here’s another Web.config file that enables tracing, instructs ASP.NET to compile debug executables, moves session state to a back-end SQL Server database (a topic you’ll learn about later in this chapter), tells ASP.NET to assume code found in the application’s files is written in C# unless otherwise noted, and enables view state validation by appending hashes to view state values round-tripped to the client:
<configuration> <system.web> <trace enabled="true" /> <sessionState mode="SQLServer" sqlConnectionString="server=localhost;uid=sa;pwd=" /> <compilation debug="true" defaultLanguage="c#" /> <pages enableViewStateMac="true" /> </system.web> </configuration>
The ultimate source of reference is Machine.config.
Configuration inheritance in the application directory structure is supported
Optional
But likely to be useful, contains
directives
event handlers
object tags
Directives:
@
Application directives - can add descriptive
information
<%@ Application Description="My First ASP.NET Application"
%>
or inheritance
<%@ Application Inherits="MyApp" %>
For code behind
@
Import directives
<%@ Import Namespace="System.Data" %>
@
Assembly directives
<%@ Import Namespace="System.DirectoryServices"
%>
<%@ Assembly Name="System.DirectoryServices"
%>
Event Handlers
Most common reason for having a global.asax file
Global.asax can also include handlers for events fired by HttpApplication instances. If present in Global.asax, the following methods are called in every request in response to HttpApplication events. They’re listed in the order in which they’re called.
Method |
Description |
Application_BeginRequest |
Called at the beginning of each request |
Application_AuthenticateRequest |
Called to authenticate the caller |
Application_AuthorizeRequest |
Called to determine whether the caller is authorized to access the requested resource |
Application_ResolveRequestCache |
Called to resolve the current request by providing content from a cache |
Application_AcquireRequestState |
Called to associate the current request with a session and populate session state |
Application_PreRequestHandlerExecute |
Called to prepend content to the HTTP response |
Application_PostRequestHandlerExecute |
Called to append content to the HTTP response |
Application_ReleaseRequestState |
Called to release (store) any state associated with this session |
Application_UpdateRequestCache |
Called to update a cache with content returned in the response |
Application_EndRequest |
Called at the end of each request |
e.g
<script language="C#" runat="server"> void Application_PostRequestHandlerExecute (Object sender, EventArgs e) { HttpApplication app = (HttpApplication) sender; app.Context.Response.Write ("<hr><center><i>" + "Copyright © 2002 by Me, Myself, and I</i></center>"); } </script>
<%@ Import Namespace="System.Diagnostics" %> <script language="C#" runat="server"> void Application_Error (Object sender, EventArgs e) { // Formulate a message to write to the event log string msg = "Error accessing " + Request.Path + "\n" + Server.GetLastError ().ToString (); // Write an entry to the event log EventLog log = new EventLog (); log.Source = "My ASP.NET Application"; log.WriteEntry (msg, EventLogEntryType.Error); } </script>
Global object tags create object instances declaratively. Suppose you want a new instance of ShoppingCart created for each user that visits your site. Rather than do this:
<script> void Session_Start () { Session["MyShoppingCart"] = new ShoppingCart (); } </script>
you can do this:
<object id="MyShoppingCart" class="ShoppingCart" scope="session" runat="server" />
Similar but Cache allows expiration dates and is preferred for that reason
In memory information about the application (cannot be persisted)
Example
HttpApplicationState properties and methods expose the contents of application state. The following statements add three stock prices keyed by stock symbols to application state and work equally in an ASPX file, in Global.asax, or in a code-behind file:
Application["AMZN"] = 10.00m; Application["INTC"] = 20.00m; Application["MSFT"] = 30.00m;
You can also add items to application state using HttpApplicationState.Add:
Application.Add ("AMZN", 10.00m); Application.Add ("INTC", 20.00m); Application.Add ("MSFT", 30.00m);
However, Add and [] behave slightly differently when adding items to application state. Add adds an item even if an item with the specified key already exists; [] does not. These statements add two separate items to application state:
Application.Add ("AMZN", 10.00m); Application.Add ("AMZN", 11.00m);
You can retrieve both items by iterating over the contents of application state, but if you simply ask for the item keyed by “AMZN,” you’ll get back 10. The following example, by contrast, adds just one item to application state. The first statement creates the item and assigns it the value 10. The second statement changes the item’s value to 11:
Application["AMZN"] = 10.00m; Application["AMZN"] = 11.00m;
How do you read values from application state? The following statements retrieve the stock prices inserted earlier:
decimal amzn = (decimal) Application["AMZN"]; decimal intc = (decimal) Application["INTC"]; decimal msft = (decimal) Application["MSFT"];
Application.Lock (); Application["ItemsSold"] = (int) Application["ItemsSold"] + 1; Application["ItemsLeft"] = (int) Application["ItemsLeft"] - 1; Application.UnLock ();
<%@ Import NameSpace="System.IO" %> <script language="C#" runat="server"> static string _path; void Application_Start () { StreamReader reader = null; try { // If Count.txt exists, read the count from it and // store the count in application state _path = Server.MapPath ("/Count.txt"); reader = new StreamReader (_path); string line = reader.ReadLine (); int count = Convert.ToInt32 (line); Application["Count"] = count; } catch (Exception) { // If Count.txt does not exist or contains an invalid // count, store a 0 in application state Application["Count"] = 0; } finally { // Close the StreamReader if (reader != null) reader.Close (); } } void Application_End () { StreamWriter writer = null; try { // Save the current count in Count.txt writer = new StreamWriter (_path, false); writer.Write (Application["Count"]); }
finally { // Close the StreamWriter if (writer != null) writer.Close (); } } </script
<%@ Page Language="C#" %> <html> <body> <% // Fetch the count and increment it by 1. Lock application state // to prevent the count from changing as it's being updated. Application.Lock (); int count = (int) Application["Count"] + 1; Application["Count"] = count; Application.UnLock (); // Write the count to the page Response.Write ("Pages in this application " + "have been requested " + count + " time"); if (count > 1) Response.Write ("s"); Response.Write ("."); %> </body> </html>
To test - run this application, close browser and run again.
Supports
Expiration dates
callbacks when item expires (thus could update the value by reinserting)
discards least recently accessed when space is needed
Can store any managed type (lie dataSet and HashTable)
Example
<script language="C#" runat="server"> void Application_Start () { Hashtable stocks = new Hashtable (); stocks.Add ("AMZN", 10.00m); stocks.Add ("INTC", 20.00m); stocks.Add ("MSFT", 30.00m); Context.Cache.Insert ("Stocks", stocks, null, DateTime.Now.AddMinutes (5), Cache.NoSlidingExpiration); } </script>
Can also be conditional on changes to datasource files,e.g
DataSet ds = new DataSet (); ds.ReadXml (Server.MapPath ("Stocks.xml")); Context.Cache.Insert ("Stocks", ds, new CacheDependency (Server.MapPath ("Stocks.xml")));
Call also set priorities for removing when space is short OR use NotRemovable
Using a callback
<%@ Import Namespace="System.Data" %> <script language="C#" runat="server"> static Cache _cache; static string _path; void Application_Start () { _cache = Context.Cache; _path = Context.Server.MapPath ("Stocks.xml"); DataSet ds = new DataSet (); ds.ReadXml (_path); _cache.Insert ("Stocks", ds, new CacheDependency (_path), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, new CacheItemRemovedCallback (RefreshDataSet)); } static void RefreshDataSet (String key, Object item, CacheItemRemovedReason reason) { DataSet ds = new DataSet (); ds.ReadXml (_path); _cache.Insert ("Stocks", ds, new CacheDependency (_path), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, new CacheItemRemovedCallback (RefreshDataSet)); } </script>
<%@ Import NameSpace="System.IO" %> <script language="C#" runat="server"> static Cache _cache = null; static string _path = null; void Application_Start () { _cache = Context.Cache; _path = Server.MapPath ("Quotes.txt"); ArrayList quotes = ReadQuotes (); if (quotes != null) { _cache.Insert ("Quotes", quotes, new CacheDependency (_path), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, new CacheItemRemovedCallback (RefreshQuotes)); } } static void RefreshQuotes (String key, Object item, CacheItemRemovedReason reason) { ArrayList quotes = ReadQuotes (); if (quotes != null) { _cache.Insert ("Quotes", quotes, new CacheDependency (_path), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, new CacheItemRemovedCallback (RefreshQuotes)); } } static ArrayList ReadQuotes () { ArrayList quotes = new ArrayList (); StreamReader reader = null; try { reader = new StreamReader (_path); for (string line = reader.ReadLine (); line != null; line = reader.ReadLine ()) quotes.Add (line); }
catch (IOException) { return null; } finally { if (reader != null) reader.Close (); } return quotes; } </script>
<%@ Import Namespace="System.IO" %> <html> <body> <asp:Label ID="Output" RunAt="server" /> </body> </html> <script language="C#" runat="server"> void Page_Load (Object sender, EventArgs e) { ArrayList quotes = (ArrayList) Cache["Quotes"]; if (quotes != null) { Random rand = new Random (); int index = rand.Next (0, quotes.Count - 1); Output.Text = (string) quotes[index]; } else { Output.Text = "Server busy"; } } </script>
An example
<%@ Page Language="C#" %> <html> <body> <% if (Session.IsNewSession ││ Session["Count"] == null) { Session["Count"] = 1; Response.Write ("Welcome! Because this is your first " + "visit to this site, a new session has been created " + "for you. Your session ID is " + Session.SessionID + "."); } else { Session["Count"] = (int) Session["Count"] + 1; Response.Write ("You have visited this site " + Session["Count"] + " times. Your session ID is still " + Session.SessionID + "."); } %> </body> </html>
Model |
Description |
In-proc |
Stores session state in-process to ASP.NET (that is, in Aspnet_wp.exe) |
State server |
Stores session state in an external “state server” process on the Web server or on a remote machine |
SQL Server |
Stores session state in a Microsoft SQL Server database on the Web server or on a remote machine |
Serializable
Session Lifetimes