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

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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






Session State

HTTP does provide a mechanism for maintaining persistent connections that allow you to identify and maintain user information. This mechanism involves using keep-alive messages to proxy servers. However, the technique is prone to error and has poor support. Therefore, as we mentioned, the HTTP protocol is effectively stateless—that is, it provides no mechanism for identifying or maintaining sessions between a Web server and a client.

Microsoft addressed this problem in ASP by providing a Session object that allowed you to uniquely identify a user and store information specific to his or her interactions with a Web server. ASP.NET offers an updated and improved version of the Session object. This object allows you to perform the following tasks:



Identify a user through a unique session ID



Store information specific to a user's session



Manage a session's lifetime through event handler methods



Release session data after a specified time-out



The ASP.NET session management facility also offers two particularly useful benefits for enterprise applications. The first of these benefits is a session state that you can maintain on a separate machine, which makes the facility suitable for deployment in multiple-machine and multiple-process scenarios. In a Web farm, the different incoming requests from a client can be processed on any machine in the Web Farm, which may be a different machine from the one that processed the previous request from the same client. If the session state is maintained on a specific machine, session is maintained regardless of which machine in the Web farm processes the request. The second benefit is the ability to store session state in a Microsoft SQL Server database. This separation provides a scalable solution and enables you to recover session state in the event of a system crash or a restart of IIS. In this chapter, we'll use the default configuration, which is to store session state on the same machine that handles the initial request from the client. For details of configuring your application to store session state on a specific machine, or in SQL Server, refer to the .NET Framework SDK documentation.

In ASP.NET, the Session object is a generic term for the System.Web.SessionState.HttpSessionState class object, which is constructed for every client session. The Session property of the System.Web.HttpApplication class (the parent class of the Global.asax page) and the Session property of the MobilePage class (the parent class of your mobile Web Forms page) both give access to the Session object. Table 12-1 shows the methods and properties of the Session object that you'll use most frequently.

























































Table 12-1: Common Methods and Properties of the Session Object


Name


Description


Methods


Abandon


Abandons the current session.


Add


Adds an item to the session state.


Clear


Clears the session state, but doesn't abandon the current session.


Remove


Removes an object from the current session state.


RemoveAll


Removes all items from the current session state.


RemoveAt


Removes an item at a given index from the current session state.


Properties


Count


Returns the number of items in the current session state.


IsCookieless


Returns a Boolean value that indicates whether the session is cookieless. (You'll learn about cookieless sessions later in this section.)


IsNewSession


Returns a Boolean value that indicates whether this request is the first of the session.


IsReadOnly


Returns a Boolean value that indicates whether the session is read-only.


IsSynchronized


Returns a Boolean value that indicates whether the session is thread-safe.


Item


Gets or sets individual session values. This is the indexer of the collection of items in the Session object, so you use this item by addressing items directly, as in this example: Session["keyname"]=value; or Session[index]=value;


Keys


Returns all the keys from the current Session object.



Using the Session Object


Typically, you'll manipulate the Session object either in the code-behind module of your application's Global.asax file or in the code-behind module of your mobile Web Forms page. Like mobile Web Forms pages, the Global.asax file supports a code-behind module. This module follows the naming convention Global.asax.extension, where extension indicates the programming language used. For example, you'd name a C# code-behind module Global.asax.cs.

The code in Listing 12-1 demonstrates two approaches for adding state data to the Session object. First, we use an indexer with a key of UserStartTime to add a string representing the user's session start time to the Session object. Second, we use the Session.Add method to define an entry with the key HelpAccess, which has an initial value of false.

Listing 12-1: Global.asax.cs file for the SessionObjectExample project






using System;
using System.Collections;
using System.Web;
using System.Web.SessionState;
namespace MSPress.MobWeb.SessEx
{
public class Global : System.Web.HttpApplication
{
protected void Session_Start(Object sender, EventArgs e)
{
Session["UserStartTime"]=DateTime.Now.ToLongTimeString();
Boolean HelpAccess=false;
Session.Add("HelpAccess",HelpAccess);
}
}
}











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

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

The mobile Web Forms page shown in Listing 12-2 includes two Form controls. On Form1, there is a Command button and a Label named Label1. The Text property of Label1 is not set here—it is set by code in the code-behind module (shown in Listing 12-3). On Form2, there are only two Label controls. One of these labels signifies that this is the Help page. The other Label control is blank—the runtime will assign its value in the code-behind module.

Listing 12-2: MobileWebForm1.aspx of the SessionObjectExample project






<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#" Codebehind="MobileWebForm1.aspx.cs"
Inherits="MSPress.MobWeb.SessEx.MobileWebForm1" %>
<mobile:Form id="Form1" runat="server">
<mobile:Label id="Label1" runat="server"/>
<mobile:Command id="Command1" runat="server">Go To Help</mobile:Command>
</mobile:Form>
<mobile:Form id="Form2" runat="server">
<mobile:Label id="Label2" runat="server">
This is a help page.
</mobile:Label>
<mobile:Label id="Label3" runat="server"></mobile:Label>
</mobile:Form>











Listing 12-3: MobileWebForm1.aspx.cs of the SessionObjectExample project






using System;
using System.Web.Mobile;
using System.Web.SessionState;
namespace MSPress.MobWeb.SessEx
{
public class MobileWebForm1 : System.Web.UI.MobileControls.MobilePage
{
protected System.Web.UI.MobileControls.Label Label1;
protected System.Web.UI.MobileControls.Label Label3;
protected System.Web.UI.MobileControls.Command Command1;
protected System.Web.UI.MobileControls.Form Form1;
protected System.Web.UI.MobileControls.Form Form2;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
this.Command1.Click += new
System.EventHandler(this.Command1_OnClick);
}
private void Page_Load(object sender, System.EventArgs e)
{
Label1.Text = "Help accessed: ";
Label1.Text += Session["HelpAccess"].ToString();
}
private void Command1_OnClick(object sender, System.EventArgs e)
{
//Switch to the Help form, set the flag in Session object
Session["HelpAccess"] = true;
Label3.Text = "Help accessed: ";
Label3.Text += Session["HelpAccess"].ToString();
ActiveForm = Form2;
}
}
}











When this simple application executes, the HelpAccess flag in the Session object is initialized as false in Global.asax.cs. When the Web Form is displayed, the code in the Page_Load method sets the label on Form1 to display the current value of the HelpAccess flag. (The message is "Help accessed: False.") The server application sends the rendering for Form1 to the client, and then terminates.

When the user clicks the Command control labeled Go To Help, the client browser posts back to the server, and during the processing of this request, the Command1_Click event handler in the code-behind module executes, fetches the HelpAccess item from the Session object and sets it to true, also setting the text of Label3 to reflect this state. The HelpAccess item was persisted in the Session object between the end of the processing of the initial client request and the start of the processing of the next request that resulted from the user clicking the Command button.


Working with Cookies


ASP.NET identifies a session by setting a session ID in an HTTP cookie, which passes between the client and the Web server with each request and response. ASP.NET uses the session ID, which it parses from the cookie, to identify and then restore state information from the Session object. The session ID is the only way ASP.NET can identify a session. Therefore, it's crucial that the session ID is unique as well as inaccessible to malicious third parties. ASP.NET ensures this by using a random encryption key (changed each time the Web server restarts) and a 32-bit session ID mixed with random data that it then encrypts to create a 16-bit cookie string. This process ensures that each session ID has a unique value and prevents hackers from guessing the algorithm that ASP.NET uses to create the IDs.

Cookies provide an invaluable way for Web servers to identify wired clients such as HTML desktop browsers. However, the potential of cookies is limited with regard to applications for wireless clients. This is because many wireless devices, including some WAP and i-mode devices, don't support cookies. If you know that your target devices support cookies or that a proxy supports them on the client's behalf, as is the case with some WAP gateways, cookies provide an excellent way to track and identify sessions. However, if you think that devices that don't support cookies will access your application, you should disable the use of cookies and use munged URLs instead. We'll discuss munged URLs in the next section.





Note

NTT DoCoMo (the Japanese mobile communications company) classifies i-mode sites as either official (in other words, sanctioned by NTT DoCoMo) or unofficial. NTT DoCoMo makes the unique ID of each i-mode handset available to the developers of official sites. The developer can use this ID in place of a cookie to track a session on the server. No such mechanism exists for unofficial sites. The WAP 2.0 specifications offer a number of ways to work with sessions and user identification—for example, by providing a unique client ID. You can read these specifications at http://www.wapforum.org/what/technical.htm.



Using Munged URLs


You can use munged URLs to pass a session ID between the client and server, rather than using a cookie. As we mentioned, a munged URL is a URL that contains a session ID, such as http://microsoft.com/myapp/(dcdb0uvhclb2b145ukpyrr55)/index.aspx

When the Web server receives the request, it parses the session ID from the munged URL. The runtime then uses the session ID the same way it would use a session ID obtained from a cookie.

Earlier you learned that cookies are the default method of passing the session ID between the client and server. However, the runtime doesn't automatically use munged URLs if the client doesn't support cookies. Instead, you must explicitly disable cookies to make the runtime use munged URLs.

You can disable cookies quite simply by setting the cookieless attribute of the sessionState element within the Web.config file. The following code fragment shows how you can disable cookie use in the Web.config file.

<!-- configuration details -->
<sessionState
mode="inProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password="
cookieless="true"
timeout="20"
/>
<!-- more configuration details -->

Note that this code fragment is taken from a standard Web.config file, and it includes lines that have meaning only if you are not storing session state on the current machine. The stateConnectionString line is used if you are storing session state on a different machine (the mode attribute is set to StateServer), and the sqlConnectionString line is used only if you are storing session state in SQL Server (mode is set to SQLServer). The timeout attribute sets the time in minutes that a session can remain idle before the session expires; this is discussed further in the section titled "ViewState," later in this chapter.

You can test whether a session is cookieless by checking the value of the read-only IsCookieless property of the Session object, like so:

if (Session.IsCookieless)
{


}



To Cookie or Not to Cookie


Considering what you've learned about mobile devices and cookie support, you might be wondering why you should bother using cookies at all and what's stopping you from using munged URLs universally. In fact, there are several reasons munged URLs aren't always the ideal solution for passing a session ID.

First, some browsers can experience difficulties dealing with relative URLs after they have been redirected to a munged URL. For example, if a browser initially requests http://servername/a.aspx and the application is configured to be cookieless, the runtime redirects the client to a URL similar to http://servername / (xyz123)/a.aspx. If the application subsequently accesses a page at the relative URL b.aspx, the browser makes a request for the URL http://servername/b.aspx, failing to use the munged URL, which includes the session identifier. The standard mobile controls allow for this restriction and always render relative URLs as properly rooted URLs, so a reference to b.aspx is rendered as /(xyz123) /b.aspx in the markup sent to the client. However, authors of custom mobile controls should be aware of this issue. The MobilePage class and DeviceAdapter base classes include helper methods that allow you to convert URLs to rooted URLs that take account of cookieless operations.

Second, ASP supports cookies but not munged URLs. Therefore, when backward compatibility is an issue, munged URLs aren't an acceptable solution. Although a developer writing an ASP application commonly included a session ID in a URL, he or she had to append the session ID to the URL to form a query string. The third disadvantage of using munged URLs is that many wireless browsers support URL lengths much shorter than those supported by desktop browsers. Thus, an application in a deeply nested hierarchy might require URLs with lengths that exceed what is supported by some browsers.

/ 145