ASP.NET - 管理状态

超文本传输协议(HTTP)是一种无状态协议.当客户端与服务器断开连接时,ASP.NET引擎会丢弃页面对象.这样,每个Web应用程序都可以向上扩展以同时处理大量请求,而不会耗尽服务器内存.

但是,需要一些技术来在请求之间存储信息并检索它在需要的时候.此信息,即当前会话中当前用户的所有控件和变量的当前值称为状态.

ASP.NET管理四种类型的状态:

  • 查看状态

  • 控制状态

  • 会话状态

  • 申请状态

查看状态

视图状态是状态页面及其所有控件.它由ASP.NET框架在帖子中自动维护.

当页面被发送回客户端时,页面属性及其控件的更改将被确定并存储在名为_VIEWSTATE的隐藏输入字段的值中.当页面再次回发时,_VIEWSTATE字段将通过HTTP请求发送到服务器.

可以启用或禁用视图状态:

  • 整个应用程序通过在< pages>中设置EnableViewState属性web.config文件的一部分.

  • 页面通过设置Page指令的EnableViewState属性,为<%@ Page Language="C#"   EnableViewState="false"  %>

  • 控件.

它是使用StateBag类定义的视图状态对象实现的,该类定义了视图状态项的集合.状态包是一个包含属性值对的数据结构,存储为与对象关联的字符串.

StateBag类具有以下属性:

属性描述
Item(名称)具有指定名称的视图状态项的值.这是StateBag类的默认属性.
Count数字视图状态集合中的项目.
Keys键的集合集合中的所有项目.
Values所有值的集合集合中的项目.

StateBag类具有以下方法:

方法描述
Add(name, value)将项目添加到视图状态集合中,现有项目为更新.
Clear从集合中删除所有项目.
Equals(Object)确定指定的对象是否等于当前对象.
Finalize允许它释放资源并执行其他清理操作.
GetEnumerator返回一个枚举器,它遍历存储在StateBag对象中的StateItem对象的所有键/值对.
GetType获取当前实例的类型.
IsItemDirty检查存储在StateBag对象中的StateItem对象,以评估它是否已被修改.
Remove(name)删除指定的项目.
SetDirty设置StateBag对象的状态以及它包含的每个StateItem对象的Dirty属性.
SetItemDirty为StateBag对象中的指定StateItem对象设置Dirty属性.
ToString返回一个stri ng表示状态包对象.

示例

以下示例演示存储视图状态的概念.让我们保留一个计数器,每次通过单击页面上的按钮回发页面时,计数器会递增.标签控件显示计数器中的值.

标记文件代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="statedemo._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

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

   <head runat="server">
      <title>
         Untitled Page
      </title>
   </head>
   
   <body>
      <form id="form1" runat="server">
      
         <div>
            <h3>View State demo</h3>
         
            Page Counter:
            
            <asp:Label ID="lblCounter" runat="server" />
            <asp:Button ID="btnIncrement" runat="server" Text="Add Count" onclick="btnIncrement_Click" />
         </div>
         
      </form>
   </body>
   
</html>


此处显示示例的代码隐藏文件:

public partial class _Default : System.Web.UI.Page
{
   public int counter
   {
      get
      {
         if (ViewState["pcounter"] != null)
         {
            return ((int)ViewState["pcounter"]);
         }
         else
         {
            return 0;
         }
      }
      
      set
      {
         ViewState["pcounter"] = value;
      }
   }
        
   protected void Page_Load(object sender, EventArgs e)
   {
      lblCounter.Text = counter.ToString();
      counter++;
   }
}


它会产生以下结果:

查看状态演示

控制状态

控制状态无法修改,直接访问,或者禁用.

会话状态

当用户连接到ASP.NET网站时,会创建一个新的会话对象.打开会话状态时,将为每个新请求创建一个新的会话状态对象.此会话状态对象成为上下文的一部分,并且可通过页面使用.

会话状态通常用于存储应用程序数据,例如库存,供应商列表,客户记录或购物车.它还可以保留有关用户及其偏好的信息,并跟踪待处理的操作.

使用120位SessionID识别和跟踪会话,该会话ID从客户端传递到服务器并作为cookie或修改后的URL返回. SessionID是全局唯一且随机的.

会话状态对象是从HttpSessionState类创建的,该类定义会话状态项的集合.

HttpSessionState类具有以下属性:

属性描述
SessionID唯一会话标识符.
Item(名称)具有指定名称的会话状态项.这是HttpSessionState类的默认属性.
Count数字会话状态集合中的项目.
TimeOut获取并设置会话状态提供程序终止会话之前请求之间允许的时间量(以分钟为单位).

HttpSessionState类有以下方法:

Methods描述
Add(name, value)将项添加到会话状态集合.
Clear删除会话状态集合中的所有项目.
Remove(name)删除会话状态集合中的指定项目.
RemoveAll删除所有键和来自t的值会话状态集合.
RemoveAt删除指定的项目来自会话状态集合的索引.

会话状态对象是用于存储和检索某些内容的名称 - 值对来自会话状态对象的信息.您可以使用以下代码:

void StoreSessionInfo()
{
   String fromuser = TextBox1.Text;
   Session["fromuser"] = fromuser;
}

void RetrieveSessionInfo()
{
   String fromuser = Session["fromuser"];
   Label1.Text = fromuser;
}


上面的代码只存储Session字典对象中的字符串,但是,它可以存储所有原始数据类型和由原语组成的数组数据类型,以及DataSet,DataTable,HashTable和Image对象,以及从ISerializable对象继承的任何用户定义的类.

示例

以下示例演示了存储会话状态的概念.页面上有两个按钮,一个用于输入字符串的文本框和一个用于显示上次会话中存储的文本的标签.

标记文件代码如下:

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

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

   <head runat="server">
      <title>
         Untitled Page
      </title>
   </head>
   
   <body>
      <form id="form1" runat="server">
         <div>
            &nbsp; &nbsp; &nbsp;
            
            <table style="width: 568px; height: 103px">
            
               <tr>
                  <td style="width: 209px">
                     <asp:Label ID="lblstr" runat="server" Text="Enter a String"  style="width:94px">
                     </asp:Label>
                  </td>
					
                  <td style="width: 317px">
                     <asp:TextBox ID="txtstr" runat="server" style="width:227px">
                     </asp:TextBox>
                  </td>
               </tr>
	
               <tr>
                  <td style="width: 209px"> </td>
                  <td style="width: 317px"> </td>
               </tr>
	
               <tr>
                  <td style="width: 209px">
                     <asp:Button ID="btnnrm" runat="server" 
                        Text="No action button" style="width:128px" />
                  </td>
	
                  <td style="width: 317px">
                     <asp:Button ID="btnstr" runat="server" 
                        OnClick="btnstr_Click" Text="Submit the String" />
                  </td> 
               </tr>
	
               <tr>
                  <td style="width: 209px">  </td>
	
                  <td style="width: 317px">  </td>  
               </tr>
	
               <tr>
                  <td style="width: 209px">
                     <asp:Label ID="lblsession" runat="server"  style="width:231px"  >
                     </asp:Label>
                  </td>
	
                  <td style="width: 317px">  </td>
               </tr>
	
               <tr>
                  <td style="width: 209px">
                     <asp:Label ID="lblshstr" runat="server">
                     </asp:Label>
                  </td>
	
                  <td style="width: 317px">  </td>
               </tr>
               
            </table>
            
         </div>
      </form>
   </body>
</html>


它在设计视图中应如下所示:

会话设计视图

这里给出了代码隐藏文件:

public partial class _Default : System.Web.UI.Page 
{
   String mystr;
   
   protected void Page_Load(object sender, EventArgs e)
   {
      this.lblshstr.Text = this.mystr;
      this.lblsession.Text = (String)this.Session["str"];
   }
   
   protected void btnstr_Click(object sender, EventArgs e)
   {
      this.mystr = this.txtstr.Text;
      this.Session["str"] = this.txtstr.Text;
      this.lblshstr.Text = this.mystr;
      this.lblsession.Text = (String)this.Session["str"];
   }
}


执行文件并观察其工作原理:

会话运行视图

应用程序状态

ASP.NET应用程序是Web服务器上单个虚拟目录中的所有网页,代码和其他文件的集合.当信息以应用程序状态存储时,它可供所有用户使用.

为了提供应用程序状态的使用,ASP.NET从HTTPApplicationState为每个应用程序创建一个应用程序状态对象. class并将此对象存储在服务器内存中.该对象由类文件global.asax表示.

应用程序状态主要用于存储命中计数器和其他统计数据,全局应用程序数据,如税率,折扣率等,并保持访问该网站的用户的跟踪.

HttpApplicationState类具有以下属性:

属性描述
Item(名称)具有指定名称的应用程序状态项的值.这是HttpApplicationState类的默认属性.
Count数字应用程序状态集合中的项目.

HttpApplicationState类具有以下方法:

方法描述
Add(name, value)将项添加到应用程序状态集合中.
Clear从应用程序状态集合中删除所有项目.
Remove(name)从应用程序状态集合中删除指定的项目.
RemoveAll从HttpApplicationState集合中删除所有对象.
RemoveAt按索引从集合中删除HttpApplicationState对象.
Lock()锁定应用程序状态集合,以便只有当前用户才能访问它.
Unlock()解锁应用程序状态集合,以便所有用户都可以访问它.

通常通过为事件编写处理程序来维护应用程序状态数据:

  • Application_Start

  • Application_End

  • Application_Error

  • Session_Start

  • Session_End

以下代码片段显示了存储应用程序状态信息的基本语法:

Void Application_Start(object sender, EventArgs e)
{
   Application["startMessage"] = "The application has started.";
}

Void Application_End(object sender, EventArgs e)
{
   Application["endtMessage"] = "The application has ended.";
}