1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 109 docx

10 353 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 228,28 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Configuring Session State Management All the code within a page refers to theSessionobject using the dictionary-style syntax seen previously, but theHttpSessionStateobject uses a Provide

Trang 1

ThePagehas a public property aptly namedSessionthat automatically retrieves theSessionfrom the

currentHttpContext Even though it seems as if theSessionobject lives inside the page, it actually lives

in theHttpContext, and the page’s publicSessionproperty actually retrieves the reference to the session

state This convenience not only makes it more comfortable for the classic ASP programmer, but saves

you a little typing as well

TheSessionobject can be referred to within a page in this way:

Session["SomeSessionState"] = "Here is some data";

or

HttpContext.Current.Session["SomeSessionState"] = "Here is some data";

The fact that theSessionobject actually lives in the current HTTP context is more than just a piece of

trivia This knowledge enables you to access theSessionobject in contexts other than the page (such as

in your ownHttpHandler)

Configuring Session State Management

All the code within a page refers to theSessionobject using the dictionary-style syntax seen previously,

but theHttpSessionStateobject uses a Provider Pattern to extract possible choices for session state

storage You can choose between the included providers by changing thesessionStateelement in

web.config ASP.NET ships with the following three storage providers:

In-Process Session State Store:Stores sessions in the ASP.NET in-memory cache

Out-Of-Process Session State Store:Stores sessions in the ASP.NET State Server service

aspnet_state.exe

Sql Session State Store:Stores sessions in Microsoft SQL Server database and is configured with

aspnet_regsql.exe

The format of theweb.configfile’ssessionStateelement is shown in the following code:

<configuration>

<system.web>

<sessionState mode="Off|InProc|StateServer|SQLServer|Custom" />

</system.web>

Begin configuring session state by setting themode="InProc"attribute of thesessionStateelement

in theweb.configof a new Web site This is the most common configuration for session state within

ASP.NET 2.0 and is also the fastest, as you see next

In-Process Session State

When the configuration is set toInProc, session data is stored in theHttpRuntime’sinternal cache in an

implementation ofISessionStateItemCollectionthat implementsICollection The session state key

is a 120-bit value string that indexes this global dictionary of object references When session state is in

process, objects are stored as live references This is an incredibly fast mechanism because no serialization

Trang 2

occurs, nor do objects leave the process space Certainly, your objects are not garbage-collected if they

exist in theIn-Process Sessionobject because a reference is still being held

Additionally, because the objects are stored (held) in memory, they use up memory until that session

times out If a user visits your site and hits one page, he might cause you to store a 40 MBXmlDocument

in in-process session If that user never comes back, you are left sitting on that large chunk of memory

for the next 20 minutes or so (a configurable value) until the Session ends, even if the user never returns InProc Gotchas

Although the InProc Session model is the fastest, the default, and the most common, it does have a

significant limitation If the worker process or application domain recycles, all session state data is lost Also, the ASP.NET application may restart for a number of reasons, such as the following:

❑ You’ve changed theweb.configorGlobal.asaxfile or ‘‘touched’’ it by changing its

modified date

❑ You’ve modified files in the\bin or\App_Codedirectory

❑ TheprocessModelelement has been set in theweb.configormachine.configfile indicating

when the application should restart Conditions that could generate a restart might be a memory limit or request-queue limit

❑ Antivirus software modifies any of the previously mentioned files This is particularly common

with antivirus software that innoculates files.

This said, In-Process Session State works great for smaller applications that require only a single Web

server, or in situations where IP load balancing is returning each user to the server where his original

Session was created

If a user already has a Session key, but is returned to a different machine than the one on which his

session was created, a new Session is created on that new machine using the session ID supplied by the user Of course, that new Session is empty and unexpected results may occur However if

regenerate-ExpiredSessionIdis set toTruein theweb.configfile, a new Session ID is created and assigned to

the user

Web Gardening

Web gardening is a technique for multiprocessor systems wherein multiple instances of the ASP.NET

worker process are started up and assigned with processor affinity On a larger Web server with as many

as four CPUs, you could have anywhere from one to four worker processes hosting ASP.NET Processor

affinity means literally that an ASP.NET worker process has an affinity for a particular CPU It’s ‘‘pinned’’

to that CPU This technique is usually enabled only in very large Web farms

Don’t forget that In-Process Session State is just that — in-process Even if your Web application consists

of only a single Web server and all IP traffic is routed to that single server, you have no guarantee that

each subsequent request will be served on the same processor A Web garden must follow many of the same rules that a Web farm follows

If you’re using Web gardening on a multiprocessor system, you must not use

In-Process Session State or you lose Sessions In-Process Session State is

appropriate only where there is a 1:1 ratio of applications to application domains.

Trang 3

Storing Data in the Session Object

In the following simple example, in aButton_Clickevent the content of the text box is added to the

Sessionobject with a specific key The user then clicks to go to another page within the same application,

and the data from theSessionobject is retrieved and presented in the browser

Note the use of the<asp:HyperLink>control Certainly, that markup could have been hard-coded as

HTML, but this small distinction will serve us well later Additionally, the URL is relative to this site, not

absolute Watch for it to help you later in this chapter

Listing 22-1 illustrates how simple it is to use theSessionobject It behaves like any otherIDictionary

collection and allows you to store keys of typeStringassociated with any kind of object TheRetrieve

.aspxfile referenced will be added in Listing 22-2

Listing 22-1: Setting values in session state

ASP.NET

<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>

ASP.NET — VB.NET

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb"

Inherits="_Default" %>

ASP.NET

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/

xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>Session State</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<asp:TextBox ID="TextBox1" Runat="server"></asp:TextBox>

<asp:Button ID="Button1" Runat="server" Text="Store in Session"

OnClick="Button1_Click" />

<br />

<asp:HyperLink ID="HyperLink1" Runat="server"

NavigateUrl="Retrieve.aspx">Next Page</asp:HyperLink>

</div>

</form>

</body>

</html>

VB

Partial Class _Default

Inherits System.Web.UI.Page

Protected Sub Button1_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Session("mykey") = TextBox1.Text End Sub

End Class

Trang 4

public partial class _Default : System.Web.UI.Page

{

protected void Button1_Click(object sender, EventArgs e)

{

Session["mykey"] = TextBox1.Text;

}

}

The page from Listing 22-1 renders in the browser as shown in Figure 22-2 TheSessionobject is accessed

as any dictionary indexed by a string key

Figure 22-2

More details about the page and theSessionobject can be displayed to the developer if page tracing is enabled You add this element to your application’sweb.configfile inside the<system.web>element,

as follows:

<trace enabled="true" pageOutput="true"/>

Now tracing is enabled, and the tracing output is sent directly to the page More details on tracing and

debugging are given in Chapter 24 For now, make this change and refresh your browser

In Figure 22-3, the screenshot is split to show both the top and roughly the middle of the large amount

of trace information that is returned when trace is enabled Session State is very much baked into the

fabric of ASP.NET You can see in the Request Details section of the trace that not only was this page

the result of an HTTP POST but the Session ID was as well — elevated to the status of first-class citizen However, the ASP.NET Session ID lives as a cookie by default, as you can see in theCookiescollection

at the bottom of the figure

The default name for that cookie isASP.NET_SessionId, but its name can be configured via the cookieN-ameattribute of the<sessionState>element inweb.config Some large enterprises allow only certain named cookies past their proxies, so you might need to change this value when working on an extranet

or a network with a gateway server; but this would be a very rare occurrence ThecookieNameis changed

to use the name ‘‘Foo’’ in the following example:

<sessionState cookieName="Foo" mode="InProc"></sessionState>

Trang 5

The trace output shown in Figure 22-3 includes a section listing the contents of theSession State

collection In the figure, you can see that the namemykeyand the valueHanselmanare currently stored

Additionally, you see the CLR data type of the stored value; in this case, it’sSystem.String

Figure 22-3

The Value column of the trace output comes from a call to the contained object’s

ToString() method If you store your own objects in the Session, you can override

ToString() to provide a text-friendly representation of your object that might make

the trace results more useful.

Now add the next page,retrieve.aspx, which pulls this value out of the session Leave theretrieve

.aspxpage as the IDE creates it and add aPage_Loadevent handler, as shown in Listing 22-2

Listing 22-2: Retrieving values from the session

VB

Partial Class Retrieve

Inherits System.Web.UI.Page

Trang 6

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _

Handles Me.Load

Dim myValue As String = CType(Session("mykey"), String) Response.Write(myValue)

End Sub

End Class

C#

public partial class Retrieve : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

string myValue = (string)Session["mykey"];

Response.Write(myValue);

}

}

Because the session contains object references, the resulting object is converted to a string by way of a

cast in C# or theCTypeorCStrfunction in VB

Making Sessions Transparent

It is unfortunate that a cast is usually required to retrieve data from theSessionobject Combined with the string key used as an index, it makes for a fairly weak contract between the page and theSession

object You can create a session helper that is specific to your application to hide these details, or you can add properties to a basePageclass that presents these objects to your pages in a friendlier way Because the genericSessionobject is available as a property onSystem.Web.UI.Page, add a new class derived

fromPagethat exposes a new property namedMyKey

Start by right-clicking your project and selecting Add New Item from the context menu to create a new class Name itSmartSessionPageand click OK The IDE may tell you that it would like to put this

new class in the/App_Codefolder to make it available to the whole application Click Yes

Your new base page is very simple Via derivation, it does everything thatSystem.Web.UI.Pagedoes,

plus it has a new property, as shown in Listing 22-3

Listing 22-3: A more session-aware base page

VB

Imports Microsoft.VisualBasic

Imports System

Imports System.Web

Public Class SmartSessionPage

Inherits System.Web.UI.Page

Private Const MYSESSIONKEY As String = "mykey"

Public Property MyKey() As String

Get Return CType(Session(MYSESSIONKEY), String) End Get

Trang 7

Set(ByVal value As String) Session(MYSESSIONKEY) = value End Set

End Property

End Class

C#

using System;

using System.Web;

public class SmartSessionPage : System.Web.UI.Page

{

private const string MYKEY = "mykey";

public string MyKey

{

get { return (string)Session[MYKEY];

} set { Session[MYKEY] = value;

} }

}

Now, return to your code from Listing 22-1 and derive your pages from this new base class To do this,

change the base class in the code-beside files to inherit fromSmartSessionPage Listing 22-4 shows

how the class in the code-behind file derives from theSmartSessionPage, which in turn derives from

System.Web.UI.Page Listing 22-4 outlines the changes to make to Listing 22-1

Listing 22-4: Deriving from the new base page

VB — ASPX

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb"

Inherits="_Default" %>

VB — Default.aspx.vb Code

Partial Class _Default

Inherits SmartSessionPage

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)

’ Session("mykey") = TextBox1.Text MyKey = TextBox1.Text

End Sub

End Class

C# — ASPX

<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>

C# — Default.aspx.cs Code

public partial class _Default : SmartSessionPage

Trang 8

protected void Button1_Click(object sender, EventArgs e)

{

//Session["mykey"] = TextBox1.Text;

MyKey = TextBox1.Text;

}

}

In this code, you change the access to theSessionobject so it uses the new public property After the

changes in Listing 22-3, all derived pages have a public property calledMyKey This property can be used without any concern about casting or Session key indexes Additional specific properties can be added as other objects are included in the Session

Here’s an interesting language note: In Listing 22-3 the name of the private string value collides with

the public property in VB because they differ only in case In C#, a private variable namedMYKEYand a

public property namedMyKeyare both acceptable Be aware of things like this when creating APIs that

will be used with multiple languages Aim for CLS compliance.

Advanced Techniques for Optimizing Session Performance

By default, all pages have write access to theSession Because it’s possible that more than one page

from the same browser client might be requested at the same time (using frames, more than one browser window on the same machine, and so on), a page holds a reader/writer lock on the sameSessionfor the duration of the page request If a page has a writer lock on the sameSession, all other pages requested

in the sameSessionmust wait until the first request finishes To be clear, theSessionis locked only for that SessionID These locks don’t affect other users with differentSessions

In order to get the best performance out of your pages that useSession, ASP.NET allows you declare

exactly what your page requires of theSessionobject via theEnableSessionState @Pageattribute The options areTrue,False, orReadOnly:

❑ EnableSessionState="True": The page requires read and write access to theSession The Ses-sionwith that SessionID will be locked during each request

❑ EnableSessionState="False": The page does not require access to theSession If the code

uses theSessionobject anyway, anHttpExceptionis thrown stopping page execution

❑ EnableSessionState="ReadOnly": The page requires read-only access to the Session A reader

lock is held on theSessionfor each request, but concurrent reads from other pages can occur

The order that locks are requested is essential As soon as a writer lock is requested, even before

a thread is granted access, all subsequent reader lock requests are blocked, regardless of whether

a reader lock is currently held or not While ASP.NET can obviously handle multiple requests,

only one request at a time gets write access to a Session

By modifying the@Pagedirection indefault.aspxandretrieve.aspxto reflect each page’s actual need, you affect performance when the site is under load Add theEnableSessionStateattribute to the pages,

as shown in the following code:

VB — Default.aspx

<%@ Page Language="VB" EnableSessionState="True" AutoEventWireup="false"

Trang 9

CodeFile="Default.aspx.vb" Inherits="_Default" %>

VB — Retrieve.aspx

<%@ Page Language="VB" EnableSessionState="ReadOnly" AutoEventWireup="false"

CodeFile="Retrieve.aspx.vb" Inherits="Retrieve" %>

C# — Default.asp

<%@ Page Language="C#" EnableSessionState="True"

CodeFile="Default.aspx.cs" Inherits="_Default"%>

C# — Retrieve.aspx

<%@ Page Language="C#" EnableSessionState="ReadOnly"

CodeFile="Retrieve.aspx.cs" Inherits="Retrieve" %>

Under the covers, ASP.NET is using marker interfaces from theSystem.Web.SessionStatenamespace

to keep track of each page’s needs When the partial class fordefault.aspxis generated, it implements

theIRequiresSessionStateinterface, whereasRetrieve.aspximplementsIReadOnlySessionState

AllHttpRequests are handled by objects that implementIHttpHandler Pages are handled by a

Page-HandlerFactory You can find more on HttpHandlers in Chapter 25 Internally, theSessionStateModule

is executing code similar to the pseudocode that follows:

If TypeOf HttpContext.Current.Handler Is IReadOnlySessionState Then

Return SessionStateStore.GetItem(itemKey)

Else ’If TypeOf HttpContext.Current.Handler Is IRequiresSessionState

Return SessionStateStore.GetItemExclusive(itemKey)

End If

As the programmer, you know things about the intent of your pages at compile time that ASP.NET can’t

figure out at runtime By including theEnableSessionStateattribute in your pages, you allow ASP.NET

to operate more efficiently Remember, ASP.NET always makes the most conservative decision unless

you give it more information to act upon

Performance Tip: If you’re coding a page that doesn’t require anything of the

Session, by all means, set EnableSessionState="False" This causes ASP.NET to

schedule that page ahead of pages that require Session and helps with the overall

scalability of your app Additionally, if your application doesn’t use Session at all,

set Mode="Off" in your web.config file to reduce overhead for the entire application.

Out-of-Process Session State

Out-of-process session state is held in a process calledaspnet_state.exethat runs as a Windows Service

You can start the ASP.NET state service by using the Services MMC snap-in or by running the following

netcommand from an administrative command line:

net start aspnet_state

Trang 10

By default, the State Service listens on TCP port 42424, but this port can be changed at the registry key

for the service, as shown in the following code The State Service is not started by default

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\

aspnet_state\Parameters\Port

Change theweb.config’s settings fromInProctoStateServer, as shown in the following code

Additionally, you must include thestateConnectionStringattribute with the IP address and port on

which the Session State Service is running In a Web farm (a group of more than one Web server), you

could run the State Service on any single server or on a separate machine entirely In this example, the

State Server is running on the local machine, so the IP address is the localhost IP 127.0.0.1 If you run

the State Server on another machine, make sure the appropriate port is open — in this case, TCP port

42424

<configuration>

<system.web>

<sessionState mode="StateServer"

stateConnectionString="tcpip=127.0.0.1:42424"/>

</system.web>

</configuration>

The State Service used is always the most recent one installed with ASP.NET That means that if you are running ASP.NET 2.0/3.5 and 1.1 on the same machine, all the states stored inSessionobjects for any

and all versions of ASP.NET are kept together in a single instance of the ASP.NET State Service

Because your application’s code runs in the ASP.NET Worker Process (aspnet_wp.exe, orw3wp.exe) and the State Service runs in the separateaspnet_state.exeprocess, objects stored in the Session can’t be

stored as references Your objects must physically leave the worker process via binary serialization

For a world-class, highly available, and scalable Web site, consider using a Session

model other than InProc Even if you can guarantee via your load-balancing

appliance that your Sessions will be sticky, you still have application-recycling

issues to contend with The out-of-process state service’s data is persisted across

application pool recycles but not computer reboots However, if your state is stored

on a different machine entirely, it will survive Web Server recycles and reboots.

Only classes that have been marked with the[Serializable]attribute may be serialized In the context

of theSessionobject, think of the[Serializable]attribute as a permission slip for instances of your

class to leave the worker process

Update theSmartSessionPagefile in your\App_Codedirectory to include a new class calledPerson, as shown in Listing 22-5 Be sure to mark it asSerializableor you will see the error shown in Figure 22-4

As long as you’ve marked your objects as[Serializable], they’ll be allowed out of the ASP.NET

process Notice that the objects in Listing 22-5 are marked[Serializable]

Ngày đăng: 05/07/2014, 19:20

TỪ KHÓA LIÊN QUAN