zoukankan      html  css  js  c++  java
  • 维护应用程序状态(二):使用会话状态

    1.2  使用会话状态

    你不可能真的用cookie来保存购物车。cookie太小也太简单了。要突破cookie的限制,ASP.NET Framework支持一个名叫Session状态的功能。

    和cookie一样,保存在Session状态中的项的作用范围是特定的用户。可以使用Session状态在多个页面请求间存储用户设置信息或其他用户相关的数据。

    和cookie不一样的是,Session状态没有大小限制。如果有极端的需求,甚至可以在Session状态中存储上G的数据。

    并且,和cookie不一样,Session状态可以保存更复杂的对象,而不像cookie只能存储简单的字符串文本。可以在Session状态中存储任意的对象。例如,可以在Session状态存储一个DataSet或者一个自定义购物车对象。

    可以使用Session对象为Session状态添加项。例如,代码清单1-9所示的页面添加一个名叫message的新项到Session状态,包含值Hello World!。

    代码清单1-9  SessionSet.aspx

    <%@ Page Language="C#" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    >

    <script runat="server">

        void Page_Load()

        {

            Session["message"] = "Hello World!";

        }

    </script>

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

    <head id="Head1" runat="server">

        
    <title>Session Set</title>

    </head>

    <body>

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

        
    <div>

        

        
    <h1>Session item added!</h1>

        

        
    </div>

        
    </form>

    </body>

    </html>

    在代码清单1-9的Page_Load事件处理中,一个新的项被添加到Session对象中。可以像使用HashTable集合那样使用Session对象。

    代码清单1-10所示的页面演示了怎样读取保存在Session状态中的项的值。

    代码清单1-10  SessionGet.aspx

    <%@ Page Language="C#" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    >

    <script runat="server">

        void Page_Load()

        {

            lblMessage.Text = Session["message"].ToString();

        }

    </script>

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

    <head id="Head1" runat="server">

        
    <title>Session Get</title>

    </head>

    <body>

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

        
    <div>

        

        
    <asp:Label

            
    id="lblMessage"

            Runat
    ="server" />

        

        
    </div>

        
    </form>

    </body>

    </html>

    当使用Session状态时,一个名叫ASP.NET_SessionId的cookie会自动添加到浏览器。这个cookie包含了一个唯一标识符。它可以在页面切换时跟踪用户。

    当添加对象到Session对象时,该对象将存储在Web服务器端上而不是Web浏览器上。ASP.NET_ SessionId用于正确地关联数据和用户。

    默认情况下,如果cookie被禁用,Session状态也不能工作了。你不会得到任何错误,但是,添加到Session状态的项目在请求后续页面时不能被访问到(后面你会了解到如何启用不依赖于cookie的Session状态)。

    注意   要小心不要过度滥用Session状态。因为会为每个请求页面的用户单独创建一份所有添加到Session状态中项的副本。如果放置一个包含400条记录的DataSet到Session状态中,并且有500个用户在请求这个页面,内存中就会有500份DataSet的副本。

    默认情况下,ASP.NET Framework假设如果用户超过20分钟不请求任何页面,则认为此用户离开了网站。此时,该用户保存在Session状态中的数据会被丢弃。

    1.2.1  在Session状态中保存数据库数据

    可以使用Session状态来创建用户相关的缓存。例如,可以为一个用户载入数据,然后允许用户排序或过滤该数据。

    代码清单1-11所示的页面载入一个DataView到Session状态中。用户可以使用GridView控件排序DataView的内容(见图1-4)。

    代码清单1-11  SessionDataView.aspx

    <%@ Page Language="C#" %>

    <%@ Import Namespace="System.Data" %>

    <%@ Import Namespace="System.Data.SqlClient" %>

    <%@ Import Namespace="System.Web.Configuration" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    >

    <script runat="server">

        DataView dvMovies;

        

        /// 
    <summary>

        /// Load the Movies

        /// 
    </summary>

        void Page_Load()

        {

            dvMovies = (DataView)Session["Movies"];

            if (dvMovies == null)

            {

                string conString = WebConfigurationManager.ConnectionStrings["Movies"].ConnectionString;

                SqlDataAdapter dad = new SqlDataAdapter("SELECT Id,Title,Director FROM Movies", conString);

                DataTable dtblMovies = new DataTable();

                dad.Fill(dtblMovies);

                dvMovies = new DataView(dtblMovies);

                Session["Movies"] = dvMovies;

            }

        }

        /// 
    <summary>

        /// Sort the Movies

        /// 
    </summary>

        protected void grdMovies_Sorting(object sender, GridViewSortEventArgs e)

        {

            dvMovies.Sort = e.SortExpression;

        }

        /// 
    <summary>

        /// Render the Movies

        /// 
    </summary>

        void Page_PreRender()

        {

            grdMovies.DataSource = dvMovies;

            grdMovies.DataBind();

        }   

    </script>

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

    <head id="Head1" runat="server">

        
    <title>Session DataView</title>

    </head>

    <body>

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

        
    <div>

        
    <asp:GridView

            
    id="grdMovies"

            AllowSorting
    ="true"

            EnableViewState
    ="false"

            OnSorting
    ="grdMovies_Sorting" 

            Runat
    ="server" />

        
    <br />

        
    <asp:LinkButton

            
    id="lnkReload"

            Text
    ="Reload Page"

            Runat
    ="server" />

        

        
    </div>

        
    </form>

    </body>

    </html>

    1-4  排序存储在Session状态中的DataView

    在代码清单1-11中,DataView对象存储在Session状态中。当排序GridView控件时,DataView也被排序。

    代码清单1-11所示的页面包含一个用来重新载入页面的链接。注意,GridView显示的记录的排序顺序有记忆性,即使在从该页面访问另一页面再返回时还是能保持。

     

    1.2.2  使用Session对象

    用户操作Session状态的最主要的应用程序编程接口是HttpSessionState类。该对象被Page.Session,Context.Session,UserControl.Session,WebService.Session和Application. Session属性暴露。也就是说,基本上可以在任何地方访问Session状态。

    HttpSessionState支持下面这些属性:

    q CookieMode——用来指定是否启用不依赖cookie的Session状态功能。可能的值包括AutoDetect、UseCookies、UseDiviceProfile和UseUri;

    q Count——用来获得Session状态中包含的项的数量;

    q IsCookieless——用来指定是否启用不依赖cookie的Session状态功能;

    q IsNewSession——用来检测当前请求是否创建了新的用户会话;

    q IsReadOnly——用来检测该Session状态是否是只读的;

    q Keys——用来获取保存在Session状态中的项目的名称列表;

    q Mode——用来指定当前的Session状态的存储处理程序。可能的值包括Custom、InProc、Off、SqlServer和StateServer;

    q SessionID——用来获得唯一的会话标识符;

    q Timeout——用来指定Web服务器端假设用户已经离开并取消Session状态的过期分钟数。最大值为525 600(1年)。

    HttpSessionState对象还包含了如下方法:

    q Abandon——用来终止一个用户会话;

    q Clear——用来清除Session状态中的所有项目;

    q Remove——用来从Session状态中删除特定的项。

    Abandon()方法允许以编程的方式终止一个用户会话。例如,你可能希望当用户登出系统时自动清除所有的用户会话状态信息。

     

    1.2.3  提交会话事件

    Global.asax中包含两个可以处理的关联Session状态的事件:Session Start和Session End事件。

    Session Start事件在一个新会话开始时被触发。可以利用该事件从数据库载入用户信息。例如,可以利用Session Start事件载入用户购物车。

    Session End事件在会话终止时被触发。会话会因用户不活动而过期或者被显式地使用Session. Abandon()方法而终止。可以利用Session End事件,例如,在希望自动保存用户的购物车到数据库表中时。

    代码清单1-12所示的Global.asax文件演示了如何处理Session Start和Session End事件。

    代码清单1-12  Global.asax

    <%@ Application Language="C#" %>

    <script runat="server">

        void Application_Start(object sender, EventArgs e) 

        {

            Application["SessionCount"] = 0;

        }

        void Session_Start(object sender, EventArgs e) 

        {

            Application.Lock();

            int count = (int)Application["SessionCount"];

            Application["SessionCount"] = count + 1;

            Application.UnLock();

        }

        void Session_End(object sender, EventArgs e) 

        {

            Application.Lock();

            int count = (int)Application["SessionCount"];

            Application["SessionCount"] = count - 1;

            Application.UnLock();

        }

        //public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)

        //{

        //    // Get anonymous profile

        //    ProfileCommon anonProfile = Profile.GetProfile(args.AnonymousID);

        //    // Copy anonymous properties to authenticated

        //    foreach (SettingsProperty prop in ProfileBase.Properties)

        //        Profile[prop.Name] = anonProfile[prop.Name];

        //    // Kill the anonymous profile

        //    ProfileManager.DeleteProfile(args.AnonymousID);

        //    AnonymousIdentificationModule.ClearAnonymousIdentifier();

        //}

        //public void Profile_ProfileAutoSaving(object s, ProfileAutoSaveEventArgs e)

        //{

        //    if (Profile.ShoppingCart.HasChanged)

        //        e.ContinueWithProfileAutoSave = true;

        //    else

        //        e.ContinueWithProfileAutoSave = false;

        //}

           

    </script>

    在代码清单1-12中,Global.asax文件用来跟踪活动会话的数量。任何时候一个新的会话开始时,Session Start事件将被触发,SessionCount变量增加1当会话终止时,Session End事件被触发,SessionCount变量减1

    SessionCount变量被保存在Application状态中。Application状态包含的项被应用程序的所有用户共享。注意,在修改Application对象时锁住了它。必须对Application对象加锁和解锁,因为在同一时间,有可能多个用户都访问Application状态中相同的项。

    注解   应用程序状态在ASP.NET中很少被使用。大多数情况下,应该使用Cache对象代替Application状态,因为Cache对象被设计成能够自动地管理内存。

    代码清单1-13所示的页面用一个Label控件显示活动会话的数量(见图1-5)。

    1-5  显示用户会话统计

    代码清单1-13  ShowSessionCount.aspx

    <%@ Page Language="C#" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    >

    <script runat="server">

        void Page_Load()

        {

            lblSessionCount.Text = Application["SessionCount"].ToString();

        }

    </script>

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

    <head id="Head1" runat="server">

        
    <title>Show Session Count</title>

    </head>

    <body>

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

        
    <div>

        

        Total Application Sessions:

        
    <asp:Label

            
    id="lblSessionCount"

            Runat
    ="server" />

        

        
    </div>

        
    </form>

    </body>

    </html>

    注意   并不是所有的会话存储处理程序都会触发Session End事件。InProc会话处理程序(默认的会话处理程序)会触发,但是StateServer或SQLServer状态处理程序就不会触发。

    3.2.4  会话失效控制

    默认情况下,ASP.NET Framework假设,过20分钟用户还不请求页面,则认为他已离开应用程序。在某些情形下,我们可能会修改默认的过期值。

    假如我们创建一个大学申请入学网站,网站包含一个让申请者输入一篇很长的文章的表单。在这种情形下,我们可能不希望用户会话在20分钟后就过期。

    增加会话的过期时间的坏处是,应用程序会消耗更多内存。会话的过期时间越长,潜在地就有可能消耗更多的服务器端内存。

    可以在Web配置文件中设置会话过期时间,或者也可以以编程的方式设置会话的过期时间。例如,代码清单1-14所示的Web配置文件将会话过期时间设为了60(1小时)。

    代码清单1-14  Web.config

    <?xml version="1.0"?>

    <configuration>

      
    <system.web>

        
    <sessionState timeout="60" />

      
    </system.web>

    </configuration>

    也可以以编程的方式设置Session对象的Timeout属性来修改会话过期时间。例如,下面的语句修改Session过期时间从20分钟到60分钟。

    Session.Timeout = 60;

    执行以上的语句后,用户会话的过期时间值就被修改了。当用户访问其他页面时,该值也一样有效。

     

    1.2.5  使用Cookieless的会话状态

    默认情况下,Session状态依赖cookie。ASP.NET Framework利用ASP.NET_SessionId这个cookie来识别跨页面请求的用户,这样,正确的数据就能关联到正确的用户。如果用户在浏览器中禁用了cookie,Session状态就不能工作了。

    如果希望在cookie被禁用时Session状态还是能工作,就应该使用无cookie的会话。当启用无cookie的会话时,用户的会话ID添加到页面的URL中。

    下面是一个启用无cookie的会话时的页面URL的样子:

    http://localhost:4945/Original/(S(5pnh11553sszre45oevthxnn))/SomePage.aspx

    URL中的奇怪的代码就是当前用户的会话ID。它的值和从Session.SessionID属性获得的值是一样的。

    可以修改Web配置文件的sessionState元素,启用无cookie的会话。sessionState元素包含一个cookieless属性接受下面的值:

    q AutoDetect——当浏览器启用cookie时,会话ID保存在cookie中,否则,会话ID添加到URL;

    q UseCookies—会话ID总是被存于cookie(默认值);

    q UseDeviceProfile——当浏览器支持cookie时,会话ID存于cookie,否则,会话ID添加到URL;

    q UseUri——会话ID总是添加到URL。

    当设置cookieless的值为UseDeviceProfile时,ASP.NET Framework通过位于下面文件夹中的一组文件查询浏览器是否支持cookie:

    \WINDOWS\Microsoft.NET\Framework\[version]\CONFIG\Browsers

    根据这些文件,如果浏览器支持cookie,则ASP.NET Framework使用cookie存储会话ID。即使浏览器禁用了cookie,框架还是会试图添加cookie。

    当cookieless的值被设为AutoDetect时,框架检查HTTP cookie头是否存在。如果cookie头被检测到,则框架在cookie中存储会话ID,否则,将会话ID添加到页面到URL。

    代码清单1-15所示的Web配置文件给cookieless属性设置了值AutoDetect,以启用不依赖于cookie的会话。

    代码清单1-15  Web.config

    <?xml version="1.0"?>

    <configuration>

      
    <system.web>

        
    <sessionState 

          
    cookieless="AutoDetect"

          regenerateExpiredSessionId
    ="true" />

      
    </system.web>

    </configuration>

    注解  测试无cookie会话的最简单方法是使用Mozilla Firefox浏览器,因为该浏览器可以非常简单地禁用cookie。选择Tools菜单项中的Options。从Privacy标签下取消选中Allow Site to Set Cookies选项。

    注意,代码清单1-16所示的配置文件还包含了一个regenerateExpiredSessionId属性。当启用无cookie的会话状态时,就应该启用该属性,因为它能帮助用户避免不小心共享Session状态。

    代码清单1-16  Web.config

    <?xml version="1.0"?>

    <configuration>

      
    <system.web>

        
    <sessionState 

          
    mode="StateServer" 

          stateConnectionString
    ="tcpip=localhost:42424" 

          stateNetworkTimeout
    ="10"  />

        
    <machineKey 

          
    decryption="AES"

          validation
    ="SHA1"

          decryptionKey
    ="306C1FA852AB3B0115150DD8BA30821CDFD125538A0C606DACA53DBB3C3E0AD2" 

          validationKey
    ="61A8E04A146AFFAB81B6AD19654F99EA7370807F18F5002725DAB98B8EFD19C711337E26948E 

          26D1D174B159973EA0BE8CC9CAA6AAF513BF84E44B2247792265"
     />

      
    </system.web>

    </configuration>

    例如,有人在一个论坛讨论区提交了一个链接,它链接到一个启用无cookie的会话状态的ASP.NET网站,它包含了会话ID。如果有人在原来的会话过期的情况下点击了该链接,则一个新的会话会自动开始。然而,如果多个用户同时点击了该链接,那么所有用户就会共享该会话ID,并且,他们就会共享相同的Session状态,这就是一个很严重的安全问题。

    而启用了RegenerateExpiredSessionId,并且会话过期时,当某人请求该页面时,URL中的会话ID会重新生成。会有一个到当前页面的重定向以修改URL中的会话ID。如果链接被发布到一个论坛讨论区,或者通过邮件发送给多个用户,则每个点击链接的用户会分配一个新的会话ID。

    当启用无cookie的会话,并在应用程序的页面间链接时,需要注意尽量使用相对URL。否则,会话ID不能自动添加到URL。

    例如,当在网站中链接另一个页面时,使用像这样的URL(一个相对URL):

    /SomeFolder/SomePage.aspx

    不要使用下面这样的URL(一个绝对URL):

    http://SomeSite.com/SomeFolder/SomePage.aspx

    如果出于某些原因需要使用绝对URL,则使用Response.ApplyAppPathModifier()方法添加会话ID到URL。该方法接受一个绝对URL,返回一个嵌入了会话ID的URL。

     

    1.2.6  配置Session状态存储

    默认情况下,Session状态被保存在ASP.NET所在的相同进程。这样做有两个主要缺点。

    首先,进程内Session状态很脆弱。如果应用程序重起,则所有的Session状态将会丢失。多种不同的事件会导致应用程序重起。例如,修改Web.config文件或者应用程序错误都能导致应用程序重起。

    其次,进程内Session状态可伸缩性较差。当Session状态保存在进程中时,它是保存在特定的Web服务器端上的。换句话说,不能在Web集群中使用进程内Session状态。

    如果需要实现更健壮的Session状态版本,则ASP.NET Framework提供许多选项。可以通过修改Session状态模式配置ASP.NET Framework存储Session状态到另一个地方。

    可以设置Session状态模式为以下值:

    q Off——禁用Session状态;

    q InProc——在ASP.NET进程所在的相同进程存储Session状态;

    q StateServer——存储Session状态到独立于ASP.NET进程的一个Windows NT进程;

    q SQLServer——存储Session状态到SQL Server数据库;

    q Custom——存储Session状态到自定义位置。

    默认情况下,Session状态模式是InProc,这是出于性能方面的考虑。进程内Session状态拥有最好的性能。然而,它牺牲了健壮性和伸缩性。

    当设置Session状态模式为StateServer或SQLServer时,我们牺牲性能换取了健壮性和伸缩性。存储Session状态到进程外,拥有更差的性能,因为,Session状态信息必须在网络上来回传递。

    最后,可以通过继承SessionStateStoreProviderBase类创建一个新类来创建自定义Session状态存储处理程序。此时,就可以保存Session状态到任何希望的地方。例如,可以创建一个Session状态存储处理程序保存Session状态到Oracle或Foxpro数据库。

    配置状态服务器端Session状态

    当启用状态服务器端(State Server)Session状态时,Session状态信息被保存在独立的Windows NT服务中。该Windows NT服务可以在Web服务器端所在的服务器端上,也可以在网络中的另一台服务器端上。

    如果保存Session状态到一个独立的Windows NT服务的内存中,则Session状态信息即使在ASP.NET应用程序不工作时也会一直存在。例如,如果我们的ASP.NET应用程序崩溃了,Session状态信息不会丢失,因为它们保存在一个独立的进程中。

    并且,可以创建一个Web集群来使用Windows NT Service保存状态信息。可以将网络中的某一台服务器端配置为状态服务器端。Web集群中的所有服务器端可以使用这个中央状态服务器端存储Session状态。

    要使用状态服务器端Session状态,必须完成下面的两个步骤:

    q 启动ASP.NET状态服务;

    q 配置应用程序使用ASP.NET状态服务。

    可以从开始菜单、控制面板、管理工具(见图1-6)打开Services小程序来启动ASP.NET状态服务。打开Services小程序后,双击ASP.NET状态服务,点击Start运行服务。应该将启动类型设为Automatic,这样服务就能在每次重起机器后自动启动。

    如果希望在网络中的一台独立的服务器端上运行ASP.NET状态服务。则需要修改部署ASP.NET状态服务的服务器端的注册表。默认情况下,ASP.NET状态服务不接受远程连接。要允许远程连接,从命令行程序执行RegEdit,设置下面的注册表键值为1

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\

    *Parameters\AllowRemoteConnection

    启动ASP.NET状态服务后,需要配置ASP.NET应用程序来使用它。代码清单1-16所示的Web配置文件启用了状态服务器端Session状态。

    1-6  启动ASP.NET状态服务

    代码清单1-16所示的Web配置文件修改了sessionState的三个属性。首先,mode属性被设为StateServer。接着,stateConnectionString属性用来指定ASP.NET状态服务器端的位置。在代码清单1-16中,连接位置被创建为在localhost,端口42424。最后,stateNetworkTimeout属性用来指定连接超时的秒数。

    注解   可以通过修改下面的注册表值来配置ASP.NET状态服务器端使用一个不同的端口:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\Port
    需要用Services小程序停止并重起ASP.NET状态服务,使修改生效。

    注意,代码清单1-17所示的Web配置文件包含了一个machineKey元素。如果安装Web集群,并且需要不同的服务器端使用相同的状态服务器端,则必须指定显式的加密和验证键值。换句话说,当ASP.NET状态服务器端就是ASP.NET应用程序所在的机器时,无需包含machineKey元素。

    代码清单1-17  Web.config

    <?xml version="1.0"?>

    <configuration>

      
    <system.web>

        
    <sessionState 

          
    mode="SQLServer"

          sqlConnectionString
    ="Data Source=YourServer;Integrated Security=True"

          sqlCommandTimeout
    ="30" />

        
    <machineKey 

          
    decryption="AES"

          validation
    ="SHA1"

          decryptionKey
    ="306C1FA852AB3B0115150DD8BA30821CDFD125538A0C606DACA53DBB3C3E0AD2" 

          validationKey
    ="61A8E04A146AFFAB81B6AD19654F99EA7370807F18F5002725DAB98B8EFD19C711337E26948E 

          26D1D174B159973EA0BE8CC9CAA6AAF513BF84E44B2247792265"
     />

      
    </system.web>

    </configuration>

    注意   不要不做任何修改就使用代码清单1-17所示的Web配置文件中的decryptionKey和validationKey属性。这些值应该保密。可以使用第21章讨论过的GenerateKeys.aspx页面为这些属性生成新的值。

    完成这些设置后,Session状态信息就被自动保存在ASP.NET状态服务器端了。当从进程内Session状态切换到过来时,不需要修改任何应用程序代码。

     

    1.2.7  配置SQL Server Session状态

    如果希望尽可能可靠地保存Session状态,那么可以保存Session状态到SQL Server数据库。因为可以设置一个失败转移(Failover)SQL Server集群。保存在SQL Server中的Session状态几乎能够在任何情况下保持有效,哪怕是遭受到非常严重的破坏。

    必须完成下面的两个步骤以启用SQL Server Session状态:

    q 配置数据库支持SQL Server Session状态;

    q 配置应用程序使用SQL Server Session状态。

    可以使用aspnet_regsql工具添加必要的表和存储过程来支持SQL Server Session状态。aspnet_regsql工具在如下路径所示的位置:

    \WINDOWS\Microsoft.NET\Framework\[version]\aspnet_regsql.exe

    注解   如果打开SDK命令行提示程序,那么不需要指定Microsoft.Net文件夹也能使用aspnet_regsql工具。

    执行下面的命令就能为名为YourServer的服务器端上的SQL Server数据库启用SQL Server Session状态。

    aspnet_regsql -C "Data Source=YourServer;Integrated Security=True" -ssadd

    当执行该命令时,一个名叫ASPState的新数据库被创建到数据库服务器端。ASPState数据库包含所有被Session状态使用的存储过程。然而,默认情况下,Session状态信息保存在TempDb数据库。当数据库服务器端重启时,TempDb数据库会自动清空。如果希望使用基于失败转移集群的SQL Server数据库,则不要使用TempDb数据库。同样地,如果希望即使数据库重启Session状态依然有效,则不要使用TempDb数据库。

    如果执行下面的命令,Session状态就被保存在ASPState数据库而不是TempDb数据库:

    aspnet_regsql -C "Data Source=YourServer;Integrated Security=True" -ssadd -sstype p

    注意,该命令包含一个 –sstype p 选项。p代表持久化。Session状态保存到ASPState数据库被称作持久化Session状态,因为即使数据库服务器端重启,Session状态依然有效。

    最后,可以保存Session状态到自定义数据库。下面的命令保存Session状态到一个名为MySessionDB的数据库中:

    aspnet_regsql -C "Data Source=YourServer;Integrated Security=True"

    *-ssadd -sstype c -d MySessionDB

    执行该命令将创建一个新的名为MySessionDB的数据库,包含用于保存Session状态的所有表和存储过程。注意,-sstype选项包含一个c代表自定义(custom)。该命令同样包含一个–d选项用于指定新数据库的名称。

    如果希望从服务器端移除Session状态表和存储过程,则可以执行下面的命令:

    aspnet_regsql -C "Data Source=YourServer;Integrated Security=True" -ssremove

    执行该命令将移除ASPState数据库。它不会删除自定义Session状态数据库。必须手动移除自定义数据库。

    配置数据库服务器端支持Session状态后,必须配置ASP.NET应用程序连接数据库。可以使用代码清单1-17所示的Web配置文件连接名为YourServer的数据库。

    sessionState元素包括三个属性。mode属性设为SQLServer以启用SQL Server Session状态。第二个属性sqlConnectionString包含连接到Session状态数据库的连接字符串。最后,sqlCommandTimeout属性指定命令读取或保存Session状态的超时时间的最大秒数。

    注意,代码清单1-18所示的配置文件包含了一个machineKey元素。如果Session状态服务器端的位置不在ASP.NET应用程序所在的服务器端,则需要包括machineKey元素,包含显式的加密和验证键值。

    注意   不要不修改decryptionKey和validationKey属性的值就使用代码清单1-17所示的Web配置文件。可以使用第2章讨论过的GenerateKeys.aspx页面为这些属性生成新的值。

    如果选择存储Session状态到自定义数据库,则当执行aspnet_regsql.exe工具时,需要在配置文件中指定自定义数据库。可以使用代码清单1-18所示的Web配置文件:

    代码清单1-18  Web.config

    <?xml version="1.0"?>

    <configuration>

      
    <system.web>

        
    <sessionState 

          
    mode="SQLServer"

          sqlConnectionString
    ="Data Source=YourServer;Integrated Security=True;database=MySessionDB"

          sqlCommandTimeout
    ="30"

          allowCustomSqlDatabase
    ="true"/>

        
    <machineKey 

          
    decryption="AES"

          validation
    ="SHA1"

          decryptionKey
    ="306C1FA852AB3B0115150DD8BA30821CDFD125538A0C606DACA53DBB3C3E0AD2" 

          validationKey
    ="61A8E04A146AFFAB81B6AD19654F99EA7370807F18F5002725DAB98B8EFD19C711337E 

          26948E26D1D174B159973EA0BE8CC9CAA6AAF513BF84E44B2247792265"
     />

      
    </system.web>

    </configuration>

    代码清单1-18所示的配置文件中的sessionState元素包含括allowCustomSqlDatabase属性。并且,allowCustomSqlDatabase属性包含自定义数据库的名称。

    启用SQL Server Session状态不会影响你编写任何应用程序代码。可以在开始的时候使用进程内Session状态,然后在需要的时候,切换到SQL Server Session状态。

  • 相关阅读:
    应该做什么样的研究:以Google为例
    机器学习问题方法总结
    浅析PageRank算法
    轮廓处理函数详细
    近视恢复方法
    一步一步深入视频接口
    什么是cookie
    Linux系统目录数和文件数限制
    九大视频接口全接触
    实时监控网卡流量的命令
  • 原文地址:https://www.cnblogs.com/greatandforever/p/1619234.html
Copyright © 2011-2022 走看看