Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] - نسخه متنی

Andy Wigley; Peter Roxburgh

نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
افزودن یادداشت
افزودن یادداشت جدید






Application State

In ASP.NET, an application is the total of all the files that the runtime can invoke or run within the scope of a virtual directory and all its subdirectories. At times, you might want to instantiate variables and objects that have scope at an application level rather than at a session level. The System.Web.HttpApplicationState class allows you to do this. The Application object is the generic term for the instance of this class for your application, which is exposed through the Application property of the System.Web.HttpApplication class (the parent class of the Global.asax page) and the Application property of the MobilePage class (the parent class of your mobile Web Forms page).

The Application object represents the ASP.NET application itself and exists as soon as any client makes the first request for a file from the given virtual directory. Because the Application object contains methods and properties similar to those of the Session object, you use the Application object in a similar way. However, unlike session information, any information the Application object stores persists between the requests of various users and remains available to all users of the application. The Application object exists in the server's memory until the Web server stops or until you modify or refresh the Global.asax file.


Using Application State in Global.asax


You can manipulate information in application state in your program code, and in the Global.asax file, which always resides at the root of a virtual directory. For the moment, you'll use Global.asax to implement event handlers associated with application state, but remember that you can also use this file to store other information such as session state, as described earlier.

You define application state data within the code-behind module of Global.asax by writing code for the two event handler methods, Application_Start and Application_End. The Application_Start event fires the first time any client accesses your application after IIS has started, or the first time a client accesses your application after the Global.asax file has been updated. The Application_End event fires when the Global.asax file has been updated; the runtime detects that the file has been changed and effectively reboots the application, so the Application_End event fires in any instances of this application that are running.

The Application object contains a dictionary-like collection to which you add objects identified by a string key. Listing 12-7 shows how you can define a global variable and add it to the Application object in the Global.asax.cs file.

Listing 12-7: Global.asax.cs of the ApplicationObjectExample project






using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
namespace MSPress.MobWeb.AppObjEx
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(Object sender, EventArgs e)
{
// Declare and assign a value to the global variable.
String AppStartTime = DateTime.Now.ToLongTimeString();
// Add the global variable to the Application object.
Application["AppStartTime"] = AppStartTime;
}
}
}











The Global.asax file that references the code-behind module in Listing 12-7 consists of a single line containing just an @ Application directive:

<%@ Application Codebehind="Global.asax.cs" 
Inherits="MSPress.MobWeb.AppStateEx.Global" %>

You can access the global variable by name through the Application object. Listing 12-8 illustrates how you can consume the global variable from the mobile Web Forms page of a project named ApplicationObjectExample.

Listing 12-8: MobileWebForm1.aspx.cs of the ApplicationObjectExample project






using System;
using System.Collections;
using System.Web;
using System.Web.Mobile;
using System.Web.SessionState;
namespace MSPress.MobWeb.AppObjEx
{
public class MobileWebForm1 : System.Web.UI.MobileControls.MobilePage
{
protected System.Web.UI.MobileControls.Label Label1;
protected System.Web.UI.MobileControls.Form Form1;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
private void Page_Load(object sender, System.EventArgs e)
{
Label1.Text = "Application started at: "
+ (Application["AppStartTime"]).ToString();
}
}
}











Listing 12-9 shows the .aspx file for the ApplicationObjectExample project.

Listing 12-9: MobileWebForm1.aspx of the ApplicationObjectExample project






<%@ Register TagPrefix="mobile" 
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#" Codebehind="MobileWebForm1.aspx.cs"
Inherits="MSPress.MobWeb.AppObjEx.MobileWebForm1" %>
<mobile:Form id="Form1" runat="server">
<mobile:Label id="Label1" runat="server">Label</mobile:Label>
</mobile:Form>















Note

Internally, the Application object is a collection of named items, similar in usage to the Session object. Methods of the HttpApplicationState class allow you to access and manipulate this collection, but by far the easiest way is to use the collection's built-in indexer to address objects in the collection directly, either by name, or by numeric index; for C#, the syntax is Application["itemName"] or Application[index]. Listing 12-8 shows how you can access a global variable from the Application object's collection using the code Application["AppStartTime"]. The HttpApplicationState object also has the Contents property, provided for backward compatibility with ASP. This property returns a reference to the HttpApplicationState object—in other words, to itself. Therefore, you can also access the value of the variable by using the syntax Application.Contents["AppStartTime"], which is useful if you are porting old ASP code to ASP.NET.


When a user first requests the mobile Web Forms page, the runtime assigns the value of the current time to the global variable AppStartTime. Figure 12-2 illustrates how the value of this variable doesn't change as the runtime makes subsequent requests for the mobile Web Forms page.


Figure 12-2: The start time of an application stored as a global variable

Whenever an instance of an application changes application state information, the runtime changes the information for all the application's users. This is demonstrated in Listings 12-10, 12-11, and 12-12, which together make up an application named SharedApplicationStateExample. In Listing 12-10, the Application_Start event handler creates a global variable in the Application object that represents a user's name.

Listing 12-10: Global.asax.cs file for the SharedApplicationStateExample project






using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;
namespace MSPress.MobWeb.SharedApplicationStateExample
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(Object sender, EventArgs e)
{
Application["LastUser"]="Nobody";
}
}
}











The Global.asax file consists of the following code:

<%@ Application Codebehind="Global.asax.cs"
Inherits="MSPress.MobWeb.SharedApplicationStateExample.Global" %>

The mobile Web Forms page that you use in this application consists of two forms. The first form prompts the user for his or her name, which the user then sends to the server by clicking the Command control. The second form consists of a label that displays the name of the last user to access the application.

Listing 12-11: MobileWebForm1.aspx file for the SharedApplicationStateExample project






<%@ Register TagPrefix="mobile" 
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#" Codebehind="MobileWebForm1.aspx.cs"
Inherits="MSPress.MobWeb.SharedApplicationStateExample.MobileWebForm1" %>
<mobile:Form id="Form1" runat="server">
<mobile:TextBox id="TextBox1" runat="server"></mobile:TextBox>
<mobile:Command id="Command1" runat="server">Enter</mobile:Command>
</mobile:Form>
<mobile:Form id="Form2" runat="server">
<mobile:Label id="Label1" runat="server">Label</mobile:Label>
</mobile:Form>











Listing 12-12 depicts the code-behind module.

Listing 12-12: Code-behind file MobileWebForm1.aspx.cs for the SharedApplicationStateExample project






using System;
using System.Collections;
using System.Web;
using System.Web.Mobile;
using System.Web.SessionState;
namespace MSPress.MobWeb.SharedApplicationStateExample
{
public class MobileWebForm1 : System.Web.UI.MobileControls.MobilePage
{
protected System.Web.UI.MobileControls.Command Command1;
protected System.Web.UI.MobileControls.TextBox TextBox1;
protected System.Web.UI.MobileControls.Form Form2;
protected System.Web.UI.MobileControls.Label Label1;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
Command1.Click += new System.EventHandler(this.Command1_Click);
}
private void Command1_Click(object sender, System.EventArgs e)
{
ActiveForm = Form2;
Label1.Text = "Previous User: " +
Application["LastUser"].ToString();
Application["LastUser"] = TextBox1.Text;
}
}
}











When the application first runs, the code in the Application_Start method in Global.asax.cs sets Application["LastUser"] to the value Nobody. The user enters his or her name and clicks the button. This causes the application to execute the Command1_Click method, which sets the text of Label1 to the value stored in Application["LastUser"] which is the name of the previous user (currently Nobody), and then stores in Application["LastUser"] the name the user has just entered in TextBox1. When the application is run again by a new user, the same process happens, but this time the name of the previous user that the application displays in Label1 is not Nobody, it's the name that the previous user entered. Figure 12-3 illustrates this process.


Figure 12-3: Displaying the previous user's name to the current user

The application object contains several methods for handling objects stored in collections. For full details about these methods, consult the ASP.NET documentation.


Things to Consider When Using Application State


At times, you might wonder whether to use session state or application state. Although application state allows you to build very powerful and flexible applications, there are several reasons you should use it with care.

First, information stored in application state is memory hungry. In other words, the application holds all application state information in memory and doesn't release the memory, even when a user exits an application. For example, you can easily make heavy demands on a server's memory by placing large datasets in application state. Second, all threads in a multithread application can access application data simultaneously because ASP.NET doesn't automatically lock resources. Therefore, if concurrent access from processes to some data stored in application scope could cause your application to fail, you should use the Enter and Exit methods of the System.Threading.Monitor .NET Framework class to ensure that a process wanting to update the data takes out an exclusive lock. (The C# lock statement is a quick way of doing the same thing.) Other than the obvious workload increase, this situation can easily affect scalability. This is because all the locks operate in a global context, meaning that the operating system blocks threads and could block all threads while waiting for a lock. Finally, unlike session state, application state doesn't persist across multiple-process or multiple-server environments. Therefore, application state is accessible only within the process in which you create it.

If you can't determine whether to use application state or session state, you should use session state. This will ensure that you avoid the problems we've just outlined.

/ 145