第四篇  应用程序

第一章 什么是应用程序

       asp.net中,可以这样来定义一个Application:能够在一个web应用服务器的子目录或者虚拟目录上运行的所有的文件、页面、操作、模块或者能被执行的代码。比方说,在一个web服务器上,一个“order“应用程序将会在“/order“这个目录下被发布。

 

       Web服务器上的asp.net应用程序在一个被称作应用程序域运行空间(AppDomain)环境中被执行,以保证类的隔离(没有版本、名称上的冲突)、安全屏蔽(防止有权访问某些机器/网络的资源)、静态变量的隔离。

 

       在一个web应用程序的生命周期中,asp.net维护一个HttpApplication实例池。Asp.net对一个Http的请求会自动分配一个来处理,这个特别的HttpApplication实例对管理这个在全部的生命周期里的请求是可靠的,并且在处理完成后可以被重用。

 

在应用程序环境下,ASP.NET并发处理客户端的请求,所以可能存在多线程对Application对象的同时存取。在这种情况下,对Application对象的草率处理,可能会导致不可预知的错误。例如以下代码:

 

<% Application("counter") = CType(Application("counter") + 1, Int32) %>

 

原本希望对实例进行计数,但如果同时到达两个以上请求时,则有可能产生漏计。正确的方法应该是在操作以前,对Application对象上锁,操作完成以后,再对Application对象解锁。代码如下:

 

<%

Application.Lock()

Application("counter") = CType(Application("counter") + 1, Int32)

Application.UnLock()

%>

 

4.1.1      配置应用程序的步骤

4.1.1.1    设置应用程序的目录结构

 

一个WEB站点可以有多个应用程序运行,而每一个应用程序可以用唯一的URL来访问,所以首先应利用IIS开放应用程序的目录为“虚拟目录”。各个应用程序的“虚拟目录”可以不存在任何物理上的关系。例如:

       应用URL:                                         物理路径:

     http://www.my.com                                         c:\inetpub\wwwroot

    http://www.my.com/myapp                        c:\myapp

       http://www.my.com/myapp/myapp1            \\computer2\test\myapp

 

从“虚拟目录上看来,http://www.my.com/myapphttp://www.my.com/myapp/myapp1是乎存在某种联系,但实际情况却是,我们看到两者完全分布于不同的机器上,更不用说物理目录了。

 

4.1.1.2.设置相应的配置文件

 

根据应用的具体需要,可以拷入相应的global.asaxconfig.web配置文件,并且设置相应的选项。(配置文件的设置具体见相关章节)

 

        global.asax主要配置application_startapplicatoin_endsession_startsession_end等事件。

 

4.1.1. 3.把应用所涉及的各种文件放入“虚拟目录“中

 

.aspx文件、.ascx文件以及各种资源文件分门别类放入应用目录中,把类引用所涉及的集合放入应用目录下的bin目录中。

 

4.1.2      应用程序框架

 

<%@ Application attribute="value" [attribute=value ]%>

<%@ Import namespace="value" %>

<%@ Assembly Name="assemblyname" %>

 

<script language=”vb”  runsat=server>

</script>

 

<body>

<form runat=server>

</form>

</body>

 

</html>

 

说明:

1<%@ Application attribute="value" [attribute=value ]%>

ASP.NET运行环境动态从另一个应用中动态编译出一个类来继承使用。

 

例如:

<%@ Application Inherits="MyApp.Object" Description="Ourapp" %>

指定应用环境从Myapp应用中动态编译一个MyApp.Object的类以供使用,它的说明为“Ourapp”

 

2<%@ Import namespace="value" %>

显视导入一个命名空间到应用程序,这样应用程序就可以使用命名空间中定义的各种类和接口来完成特定的功能,大大加快了程序的开发速度。

 

例如:

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

<%@ Import Namespace="System.NET” %>

就可以利用系统为我们提供的大量文件和网络对象,快速的开发自己的文件和网络应用程序。

 

3<%@ Assembly Name="assemblyname" %>

在页面编译时产生到assemblyname的连接,这样就可以使用集合中类及接口。缺省情况下,应用会把应用程序目录下bin中的集合都动态载入。该项功能也可以在应用程序的config.web中配置,缺省情况下,config.web中有如下形式:

 

<assembly>

<add assembly="*"/>

</assembly>

 

即缺省情况下,加载bin下的所有集合。

又如:

<%@ Assembly Name="myassembly.dll" %>

       加载binmyassembly.dll集合

 

4.其他

<script></script>对之间的代码通常是各种事件的定义,诸如页面开始时、某个按件被触发时所要做的事情。<body></body><form></form>之间通常是页面的界面要素,为显示给客户端的可视界面。

4.1.3      创建应用程序的典型步骤

4.1.3.1    配置config.web

 

主要定义为gb2312字符集,以利于中文显示

<configuration>

<globalization requestencoding="gb2312" responseencoding="gb2312" />

</configuration>

 

4.1.3.2    配置global.asax

 

主要定义应用初始化、结束,会话开始、结束,请求开始、结束等事件发生时,应用要做的事情。

 

<script language="VB" runat="server">

Sub Application_Start(Sender As Object, E As EventArgs)

End Sub

 

Sub Application_End(Sender As Object, E As EventArgs)

End Sub

 

Sub Session_Start(Sender As Object, E As EventArgs)

End Sub

 

Sub Session_End(Sender As Object, E As EventArgs)

End Sub

 

Sub Application_BeginRequest(Sender As Object, E As EventArgs)

End Sub

 

Sub Application_EndRequest(Sender As Object, E As EventArgs)

End Sub

 

</script>

 

4.1.3.3    主程序

 

创建一个应用程序我们可以先在web服务器上创建一个虚拟目录或者在发布目录下创建一个新的目录。装过Windows 2000 Advance Server的读者会知道,安装完成后,会有一个c:/inetpub/wwwroot的目录,你可以通过IIS管理工具来创建一个新的目录或者虚拟目录。一个应用程序可能含有大量的.aspx文件、.ascx文件、由其他工具产生的assembly集合以及页面中用到的各种资源文件(声音、图片、动画等等),这里就不再一一介绍了。

 

       下面我们就创建一个简单的aspx页面来说明一个Application的应用,它只含有一个.aspx文件,在用户浏览时显示“hello world”,可谓最简单的web应用了。

 

<!-- 文件名:application/FormAppHellp.aspx -->

<%@Page Language="VB"%>

<html>

     

 <head>

  <title>

    hello world

  </title>

 </head>

 

 <body>

  <center>

   <h1><% Response.Write("Hello World!") %></h1>

  </center>

 </body>

 

</html>

 

下面就是我们的运行效果:

 

4.1.4      小结

asp.net平台的应用,通过指定虚拟目录,使得一个主机多个地址多个应用成为可能。采用asp.net开发应用程序带来的好处是:程序集中可方便打包,配置的层次结构更加灵活方便,应用独立运行于自身的应用环境中更加安全可靠。

 

配置一个应用的过程大致为:1)指定应用目录为IIS的虚拟目录2)为应用设置适当的配置权限(配置global.asaxconfig.web文件)3)在自己的应用目录下放置事先编好的程序。

从页面应用所支持的ApplicationImportAssemly等标识看来,asp.net对对象重用的支持大大加强了,ASP.NET的“通用语言运行库”概念的提出,为实现各种开发语言的合作编程奠定了基础。

 

第二章 配置Config.web

4.2.1      ASP.NET配置简介

ASP.NET提供了一个丰富而可行的配置系统,以帮助管理人员轻松快速的建立自己的WEB应用环境。ASP.NET提供的是一个层次配置架构,可以帮助WEB应用、站点、机器分别配置自己的扩展配置数据。ASP.NET的配置系统具有以下优点:

              ASP.NET允许配置内容可以和静态内容、动态页面和商业对象放置在同一应用的目录结构下。当管理人员需要安装新的ASP.NET应用时,只需要将应用目录拷贝到新的机器上即可。

              ASP.NET的配置内容以纯文本方式保存,可以以任意标准的文本编辑器、XML解析器和脚本语言解释、修改配置内容。

              ASP.NET 提供了扩展配置内容的架构,以支持第三方开发者配置自己的内容。

              ASP.NET配置文件的更修被系统自动监控,无须管理人员手工干预。

 

4.2.2      配置文件的规则

ASP.NET的配置文件是基于XML格式的纯文本文件,存在于应用的各个目录下,统一命名为“config.web”。它决定了所在目录及其子目录的配置信息,并且子目录下的配置信息覆盖其父目录的配置。

WINNT\Microsoft.NET\Framework\版本号\下的config.web为整个机器的根配置文件,它定义了整个环境下的缺省配置。

缺省情况下,浏览器是不能够直接访问目录下的config.web文件。

在运行状态下,ASP.NET会根据远程URL请求,把访问路径下的各个config.web配置文件叠加,产生一个唯一的配置集合。举例来说,一个对URL: http://localhost\webapp\owndir\ test.aspx的访问,ASP.NET会根据以下顺序来决定最终的配置情况:

       1..\Microsoft.NET\Framework\v.1.00\config.web (缺省配置文件)

       2..\webapp\config.web                                    (应用的配置)

       3..\webapp\owndir\config.web                         (自己的配置)

4.2.3      配置文件的语法规则

1)标识

配置内容被置于config.web文件中的标记<configuration></configuration>之间。

格式:

<configuration>

       配置内容

       </configuration>

 

       2)配置段句柄说明

       ASP.NET的配置文件架构并未指定任何文件格式或者是支持的配置属性。相反的,它提出了“配置段句柄申明”的概念来支持任意的用户定义配置段。

       格式:

       <configsections>

              <add name=欲定义配置段名 type=处理的句柄函数 />

       </configsections>

      

3)配置段

具体定义配置的内容,供应用使用。

 

以下例子定义了一个“httpmodules”配置段,设置了系统http相关的处理模块

 

<configuration>

 

    <configsections>

        <add name="httpmodules" type="System.Web.Configuration.HttpModules

ConfigurationHandler" />

    </configsections>

 

    <httpmodules>

        <add type="System.Web.SessionState.CookielessSessionModule" />

        <add type="System.Web.Caching.OutputCacheModule" />

        <add type="System.Web.SessionState.SessionStateModule" />

        <add type="System.Web.Security.WindowsAuthenticationModule" />

        <add type="System.Web.Security.CookieAuthenticationModule" />

        <add type="System.Web.Security.PassportAuthenticationModule" />

        <add type="System.Web.Security.CustomAuthenticationModule" />

        <add type="System.Web.Security.UrlAuthorizationModule" />

        <add type="System.Web.Security.FileAuthorizationModule" />

    </httpmodules>

 

</configuration>

 

4.2. 4     ASP.NET定义的标准配置段

1)httpmodule    段:  定义了应用的http请求的处理模块以及诸如安全、日志之类的应用方式

2)httphandlers    段: 负责映射URLsIhttpHandler

3)sessionstat     段:  负责配置http模块的会话状态

4)globalization   段:  配置应用的公用设置

5)compilation    段:  配置ASP.NET的编译环境

6)trace       段:  配置ASP.NET的跟踪服务

7)security        段: ASP.NET的安全配置

8)iisprocessmodel 段: 在IIS上配置ASP.NET的处理模式

9)browercaps     段: 配置浏览器的兼容部件

4.2. 5     一个配置读出的例子

1)config.web配置文件

 

<!--config.web 请放入FormCfg.aspx所在目录-->

<configuration>

<!--申明一个test配置段-->

    <configsections>

        <add name="test" type="System.Web.Configuration.DictionarySectionHandler" />

    </configsections>

 

    <test>

<!--配置一个键key,其内容为just a configure test-->

 

        <add key="key" value="just a configure test" />

    </test>

   

</configuration>

 

2)读出其内容

 

<!--文件名:Application/FormCfg.aspx-->

<html>

 <head>

<script language="VB" runat=server>

sub page_load(s as object ,e as eventargs)

'取出test配置段的key键的值

        Dim CfgSection As Hashtable = Context.GetConfig("test")

        Dim Msg As String = CStr(CfgSection("key"))

 

       lblMsg.text=Msg

end sub

</script>

 <title>

配置信息的读取

  </title>

 </head>

 

<body>

<center>

config.web"test"配置段中key的内容为:

<asp:label id=lblmsg runat=server />

</center>  

</body>

 

</html>

 

3)运行结果

 

 

4.2. 6     Config.web配置实例

<configuration>

<!--定义用户应用的公用设置,如SQLsql连接串等等-->

<appsettings>

</appsettings>

 

<!--设置浏览器的兼容性部件-->

<browsercaps>

</browsercaps>

 

<!--编译环境设置,非调试模式-->

<compilation debugmode="false">

<!--缺省编译语言为vb,以后可以不再在Page中定义脚本语言-->

<compilers defaultlanguage="vb">

<!--MSVSA.dll编译.vb为后缀的VB文件-->

<compiler language="VB" extension=".vb" type="MSVSA.dll#Microsoft.VB.Compiler"/>

</compilers>

 

<assemblies>

<!--加入对System.Data的引用-->

<add assembly="System.Data" />

<!--去掉对System.Data的引用-->

<remove assembly="System.IO" />

<!--去掉config.web中包含或继承来的引用-->

<clear />

</assemblies>

 

</compilation>

 

<!--设置应用全局环境-->

<!--文件、请求、返回以gb2312编码,以保证浏览器正确显示中文-->

<globalization fileencoding="gb2312"  requestencoding="gb2312"

responseencoding="gb2312"/>

 

<!--定义用户出错的处理-->

<!--出错缺省显示defaultredirect指定的页面,modeon时,遵循customerrors配置段-->

<!--modeoff,忽略用户出错,moderemoteonly时,本地才显示真正的出错原因-->

<customerrors defaultredirect="AnErrorHasOccured.aspx?ErrNum=-1" mode="remote">

<!--当出错码为500,显示redirect指定的页面-->

<error statuscode="500" redirect="AnErrorHasOccured.aspx?ErrNum=500"/>

</customerrors>

 

<!--指定目录webapp的访问权限-->

<location path="webapp” >

<!--非授权用户不能进入webapp目录-->

<security>

<authorization>

<deny users="?" />

</authorization>

</security>

</location>

 

<!--定义安全属性-->

<security>

<authorization>

<!--角色为Adminstrators和所有的用户访问其指定的资源-->

<allow roles="Adminstrators"/>

<allow users="*" />

</authorization>

</security>

 

</configuration>

 

4.2.7      小结

Config.webaspx区别于asp的一个方面,我们可以用这个文件配置我们的很多信息。

第三章 编写global.asax

       为了编写用户界面的应用程序,开发者可以把应用程序标准的逻辑和时间处理的代码加到Web Application 里面。这些代码不产生用户界面,也不想英单个得页面的请求。事实上,这些代码处理更高水平的事件,如Application_Start, Application_End, Session_Start, Session_End,等等。开发者通过放在web应用程序根目录下面的Global.asax来响应这些事件。

      

       Asp.net通过一个动态的.NET FrameWork 类自动解析和编译这个文件,这个类就是HttpApplication基类,在第一时间里面,在这个文件里面的应用程序的资源将会被响应。

      

       首先,在包含有请求的应用程序名字空间中被访问之前,Global.asax将被解析和编译成.NET Framework的一个类。这个文件本身有拒绝被访问的配置。

      

       下面我们来看看这个文件里面的具体内容,首先我们声明这个文件的使用语言、运行环境:

      

       <script language=”VB” runat=server>

       ‘相关方法

       </script>

 

然后我们就可以定义各种方法了,

      

       Sub Application_Start()

              ‘方法的属性等

End Sub

 

如果事件处理代码需要用到名字空间,我们可以这样来引用它:

      

       <%@  Import  Namespace=”System.Data.SQL”%>

 

下面我们来看看这个文件的具体应用,首先我们在我们的Web Server上建立一个Global.asax文件,我们在里面加上我们的代码:

 

<script language=”VB” runat=server>

相关方法

 

Sub Application_Start()

              ‘方法的属性等

End Sub

 

Sub Application_Start(Sender As Object, E As EventArgs)

       Application.Lock()

       Application("counter") = CType(Application("counter") + 1, Int32)

       Application.UnLock()

   End Sub

 

    Sub Application_End(Sender As Object, E As EventArgs)

        ' Clean up application resources here

    End Sub

 

    Sub Session_Start(Sender As Object, E As EventArgs)

        Response.Write("Session 正在启动...<br>")

    End Sub

 

    Sub Session_End(Sender As Object, E As EventArgs)

        ' Clean up session resources here

    End Sub

       </script>

 

当然,我们还要配置Config.web,用来指定出错信息的打印页面。根据上面我们配置Config.web的经验,我们很容易的就可以对这个文件进行配置:

 

       <configuration>

    <customerrors mode="on" defaultredirect="error.htm" />

    <globalization requestencoding="gb2312" responseencoding="gb2312" />

</configuration>

 

第二句话就是配置我们指定的出错页面语句。我们写两个页面来实现它,一个为出错页面,一个为实现这个功能的aspx页面。出错页面很简单的,就是报告程序出错时显示的信息,我们就写“在config.web里面配置的连接!“,是经过aspx页面甩出来的。

aspx页面,我们用下面的语句来响应出错按钮点击事件:

 

Sub Error_Click(Sender As Object, E As EventArgs)

               ‘甩出异常!

         throw New Exception()

End Sub

 

以外我们的响应Session的方法用下面的语句来说明:

      

       Sub Session_Click(Sender As Object, E As EventArgs)

         Session.Abandon()

         Response.Redirect("global.aspx")

End Sub

 

下面是完整的代码:

      

       <html>

   <script language="VB" runat="server">

      '页面导入

      Sub Page_Load(Sender As Object, E As EventArgs)

         Response.Write("正在装入页面...<br>")

      End Sub

 

      'Session事件

      Sub ssaidy(Sender As Object, E As EventArgs)

         Session.Abandon()

         Response.Redirect("global.aspx")

      End Sub

 

      '响应错误方法

      Sub esaidy(Sender As Object, E As EventArgs)

        '抛出异常

         throw New Exception()

      End Sub

  </script>

  <body>

   <br><br><br>

   <center>

    <form runat="server">

      <input type="submit" Value="刷新这个页面" runat="server"/>

      <input type="submit" OnServerClick="ssaidy" Value="结束这个Session" runat="server"/>

      <input type="submit" OnServerClick="esaidy" Value="错误表示" runat="server"/><p>

      <hr>

    </form>

    </center>

    <br><br>

  </body>

</html>

 

运行结果如下:

      

 

点击“错误表示“按钮,显示如下:

      

      

 

4.3.1小结

讲述了配置文件Global.asax的配置问题,Global.asax文件对一个.NET技术构建的WEB站点来讲,是非常必须的,本章我们的内容就是针对它讲的。

第四章 Application和Session

4.4.1      Application对象

在讲述ASP.NETApplication对象之前,我们先来回顾一下ASPApplication对象。我们知道由于变量的生命周期受限于网页,所以每当.asp文件被解释执行完毕之后时,变量就会被释放,它的内容将不存在。而在编程过程中,我们有时又需要在页面之间传递变量的内容。例如,我们在一个登录页面中输入了用户的名字,为了使页面个性化,在后面的页面显示中,我们希望知道前面输入的用户名,以便于更好的人机交互。这就要求有一种变量传递的机制。人们最常用的保存变量的内容的方法是使用文件,但是毕竟对文件的的操作是比较麻烦的事情,有没有更简单的方法呢?其中一种比较简单的方法就是使用Application对象来保存我们希望传递的变量。由于在整个应用程序生存周期中,Application对象都是有效的,所以在不同的页面中都可以对它进行存取,就像使用全局变量一样方便。在asp.net环境下,Application对象来自HttpApplictionStat类。它可以在多个请求、连接之间共享公用信息,也可以在各个请求连接之间充当信息传递的管道。

4.4.1.1    使用Application对象

       Application对象重要的属性

 

       ·All属性,返回应用中保存的所有的公用对象数组

              例如:

dim MyObjects() as object

MyObjects=Application.All

              表示用myobjects取得了当前应用保存的所有对象

 

       ·AllKeys属性,返回应用中保存的公用对象的名字数组(标识数组)

例如:

         dim MyVars() as String

     MyVars=Application.AllKeys

 即取得了所有保存的公用对象的标识名字到myvars数组

 

·Contents属性,返回this指针,主要是为了和asp兼容而保留

 

·Count属性,返回当前应用中保存的公用对象的数目

  例如:

          dim VarNum as integer

       VarNum=Appliction.count

      

·Item属性,返回当前应用中保存的公用对象集合中的指定对象,这是最常用的属性。

  例如我们前面讨论的,记录变量内容的问题,就是通过item属性来保存的。

      Appliction.Item(变量名)=要保存对象

  但是通常我们都会省去item属性写成:

Application(变量名)=要保存对象

       这里需要注意的是,Application保存的对象为应用程序所共享,而.net平台又是一个多用户多线程的环境,因而Application保存的对象在使用时,要注意避免冲突。

例如:

Application”counter”= Application”counter”+1

它使开始用户保存的数值加1,我们可以利用它来统计页面浏览的次数。但是有一个问题发生了,那就是如果另外一个页面也使用了上述语句,那么混乱就产生了。设想一下如下情况,用户a对页面a访问,使counter+1,然后用户b对页面b的访问,counter又增加了1,实际上无论对页面a还是页面b,访问都只有一次,counter却增加了2次,由于记数变量的相同使得我们统计页面的努力化为泡影。

 

·StaticObjects属性,返回在应用程序文件中型如<object runat=server></object>定义的对象的集合。

 

下面,我们对上面学到的各种属性进行应用。

例子:

       我们首先产生6Application变量,然后分别用item属性和all属性去逐一取出各个Application变量的内容显示出来。注意为了避免其他公用Application变量的干扰,我们在页面加载时,调用了removeall方法,清空应用的所有公用变量。

 

1.  程序源代码

<!-- 文件名:Application\FormAppliction.aspx -->

 

<html>

 

 <script language="vb" runat=server>

   Sub Page_Load(o as object,e as eventargs)

 

    dim i as integer

    dim tStr as String

    dim sStr as String

    dim strArray() as String

    dim tObject() as Object

    dim ObCol as HttpStaticObjectsCollection

 

   If Not IsPostBack

         Application.removeall

        '为防止其他变量干扰,使用前清掉所有的保存变量

 

        '保存六个变量

         for i=1 to 6

         tStr="变量名" & i

          sStr="内容" & i

         Application(tStr)=sStr

         next

   Else

       '采用item属性遍历

       response.write("<center><b>采用item属性显示</b></center><br>")   

       strArray=Application.Allkeys

       for i=1 to Application.count

       tStr= strArray(i-1) & "=" & Application.item(i-1)&"&nbsp;&nbsp;"

       response.write(tStr)

       next

      

       '采用All属性遍历

       response.write("<hr><center><b>采用All属性显示</b></center><br>")

       tObject=Application.All

       for i=1 to Application.count

       tStr=tObject(i-1).ToString & "&nbsp;&nbsp;"

       response.write(tStr)

       next

      

       '显示有多少个object定义

       ObCol=Application.StaticObjects

       response.write("<hr>含有object标识:" & ObCol.count & "")

    

  End If      

   End Sub

 </script>

 

 <head>

  <title>

  Appliction对象试验

  </title>

 </head>

 

 <body bgcolor=#ccccff>

  <center>

   <h2>Appliction对象试验</h2>

   <hr>

    <form runat=server>

       <asp:button text="显示Appliction内容" runat=server />

    </form>

  </center>

 </body>

</html>

 

2.开始时,页面的输出画面

 

       3.当按下显示按钮后,显示appliction内容的画面:

 

 

 

Application对象重要的方法调用:

 

       ·Add方法,加入一个对象到Application对象的Stat集合中

              例如:

                     Application.Add(“string1”,”test”)

              表示向Applicationstat集合中加入一个名为string1的值为”test”的字符串,其实它的效果和

Application(“string1”)=”test”

以及Application.item(“string1”)=”test”       是一样的。

 

·Remove方法,根据给出的标识从Application对象的Stat集合中删去

    例如:

              Application.Remove(“string1”)

    表示把标识为string1的共享对象string1Application对象的Stat集合中删去。使用它可以清除用Add方法添加的对象。

 

       ·RemoveAll方法,把Application对象Stat集合中的所有对象清除,在我们对属性的使用举例中,我们已经见过了它的用法,但是值得小心,我们不提倡使用它,因为在编程中你并不清楚,是否有其他页面要依赖于某个Application的公用变量,一旦清除将造成不可预知的错误。

 

       ·Clear方法,作用和RemoveAll方法一样。

             

       ·Get方法,允许使用名字标识或者是下标,来取得Application对象stat集合中的对象元素。

       例如:

              dim tmp as object

              tmp=Application.Get(“string1”)

        或者 tmp=Application.Get(0)

       表示从Application对象的Stat集合中取得标识为string1或者下标为0的对象

       它等价于:

              tmp=Application(“string1”)

        tmp=Application(0)

       或者是

        tmp=Application.item(“string1”)

              tmp=Application.item(0)

 

       ·Set方法,修改Application对象stat 集合中指定标识所对应的对象的值。

              例如:

                     Application.Set(“string1”,”try”)

              就把我们开始为string1变量设置的值”test”改为”try”了,它和下边的形式也是一样的:

                     Application(“string1”)=try

 

·GetKey方法,根据给定的下标取得Application对象的stat集合中相应对象的标识名。

例如:

       dim nameStr as String

       nameStr=Application.GetKey(0)

       表示取得Application对象中Stat集合的第一个对象的标识名

 

       ·Lock方法,锁住其他线程对Application对象中stat集合的访问权限。这个方法主要是用来防止对Application的变量操作过程中,其他并发程序可能造成的影响。比如在记数过程中,如果不进行上锁操作,就有可能发生脏读脏写。例如,开始从变量中取得记数值1

如果在记数并写回到变量之间,另一页面对它发生了一次记数,并先行写回变量,那么最终写回到变量中的值为2,而并不是实际的3。如果采用了上锁机制,在页面读出变量到记数并写回变量的过程中,即使发生了另一次记数,由于变量被锁住,它也不可能在变量被写回以前取得成功,只有等待变量释放,从而形成两者对变量操作的串行性,避免了数据的脏读和脏写。

 

       ·Unlock方法,对Application对象Stat集合锁定的解锁操作,释放资源以供其他页面使用。

 

       下面我们就上边学到的方法做一个例子,为了强调lock方法和unlock方法,我们将单独举一个例子。例子是这样的,开始我们创建6Application变量,赋以数值序号,页面有3个按钮,分别是加1,减1和清除。当点击“加1“按钮后,我们会看到变量的值都会增加1,当点击”减1“按钮后,变量值都减1,当按下清除后,变量都消失了。在清除功能中,我们为了同时演示removeclear方法,采用最后三个用clear清除,其他的逐一用remove清除。

 

1.  源程序

 

<!-- 文件名:Application\FormApplication01.aspx -->

 

<html>

 

 <script language="vb" runat=server>

 

   Sub Page_Load(o as object,e as eventargs)

   dim i as integer

 

       If Not IsPostBack

        for i=1 to 6

         application.add("item"&i,i)

         next                   

     End If

 

    response.clear   

     for i=0 to application.count-1

     response.write(application.GetKey(i) & "=" & application.Get(i) & "<br>")

     next

          

   End Sub

 

  Sub AddOne(s as object,e as eventargs)

  '变量值加1

   dim i as integer

   dim j as integer

   dim t as string

   

   for i=0 to Application.count-1

   j=Application.Get(i)+1

   t=Application.GetKey(i)

   Application.Set(t,j)

   next   

 

  Page_Load(s,e)

  '刷新画面

  End Sub

 

  Sub SubOne(s as object,e as eventargs)

  '变量减1

   dim i as integer

   dim j as integer

   dim t as string

   

   for i=0 to Application.count-1

   j=Application.Get(i)-1

   t=Application.GetKey(i)

   Application.Set(t,j)

   next   

 

   Page_Load(s,e)

   '刷新画面

  End Sub

 

  Sub Gone(s as object,e as eventargs)

  '清空所有变量

   dim i as integer

 

   for i=0 to Application.count-3

   Application.Remove(i)

   next

   '演示remove方法

   Application.clear

   '演示clear方法

   Page_Load(s,e)

   '刷新画面

  End Sub

 </script>

 <head>

  <title>

  Application方法试验

  </title>

 </head>

 <body bgcolor=#ccccff>

  <center>

   <h2>Application方法试验</h2>

   <hr>

    <form runat=server>

      <asp:button type="submit" text="+1" OnClick="AddOne" runat=server />

      <asp:button  type="submit" text="-1" OnClick="SubOne" runat=server />

      <asp:button  type="submit" text="清空" OnClick="Gone" runat=server />

    </form>

  </center>

 </body>

</html>

 

       2.开始时,输出画面:

 

3.当两次点击+1后,输出的变量值:

 

 

       4.当点击”-1”后,变量的值为:

 

 

 

       5.当点击清空后,输出的画面

 

 

       接下来,我们看一个使用lockunlock方法制作计数器的例子:Application对象对不同的连接者是共用的,因此适合制作计数器。

 

程序代码如下:

 

<!-- 文件名:application\FormAppLock.aspx -->

<html>

 <script language="vb" runat=server>

  sub Page_Load(o as object,e as eventargs)

   Application.Lock()

   Application("counter") = CType(Application("counter") + 1, Int32)

   Application.UnLock()

  end sub

</script>

 

<head>

 <title>

   Application对象方法试验

 </title>

</head>

 

<body>

 <center>

  <h2>Application对象Lock方法试验</h2>

  <hr>

你是第<%=Application("counter")%>位访问者!

 </center>

</html>

 

效果图:

 

 

关于计数器非同步更新的问题

假设有两个上网者同时启动网页(这种情况很常见),同时执行了上面的步骤,他们读出的值是相同的,但结果都是相同的。很明显,访问量少了一次。如何处理呢?我们在这里举一个例子,假设我们都在使用一个数据库管理系统,有可能访问者同时对一张表进行操作,如果一人在修改这张表的数据,而另一个人在读数据,很明显此时数据前后就不一致。通过我们需要对表进行锁定。那么,我们可以锁定对象,程序修改为:

Application.lock

Application("counter") = CType(Application("counter") + 1, Int32)

Application.unlock

这样,当某一程序执行了Application.lock之后,其他应用程序就暂时不能使用Application对象,直到Application unlock

4.4.1.2    Application的事件

    Application对象的生命周期开始时,Application_onstart 事件会被启动,当Application对象的生命周期结束时Application_onend事件会被启动。通常我们会在global.asax中定义

Application_onstart 事件。这和ASP程序相类似,有一点差别是Application_onstart 事件是在global.asa中定义。还有就是除了以前的四个事件又 增加了 两个事件Application_BeginRequest事件 Application_EndRequest事件。

在上一个例子中我们实现了用计数器来对页面进行统计,但是这样的程序有这样的一个问题,就是只能统计单个的页面,我们在asp+中可以很轻松的实现对整个站点页面的统计。为了达到这个目的,我们使用将使用Application_BeginRequest事件和 Application_EndRequest事件。这两个事件在站点的任意一个文件被请求的时候都会被激发,因此我们便利用这个事件实现对站点的访问统计。

 

我们首先来看看这个global.asax 文件

<script language="VB" runat="server">

Sub Application_End(Sender As Object, E As EventArgs)

'我们捎带实现了 站点的当前在线人数

dim intOnlineNumber as integer

intOnlineNumber=cInt(Application("ONLINENUMBER"))-1

Application("ONLINENUMBER")=intOnlineNumber

End Sub

 

Sub Session_Start(Sender As Object, E As EventArgs)

Application.Lock

intOnlineNumber=cInt(Application("ONLINENUMBER"))+1

Application("ONLINENUMBER")=intOnlineNumber+1

Application.UnLock

End Sub

Sub Application_BeginRequest(Sender As Object, E As EventArgs)

response.write("当前访问的页面是 " + Request.FilePath + "<br>")

'既然我们可以得到FilePAth 则我们只要把这个参数进行详细的各种各样的统计就可以了

End Sub

</script>

'好了一切完结之后,我们访问站点的任意一个aspx 文件,都会在最上方发现一行文字:当前访问的页面是 。。。。

怎么样,还不赶快尝试一下??

 

4.4.2      Session

4.4.2.1    Asp.net里的Session

Session的应用,我们通过在Global.asax中设置,然后在aspx页面中调用来进行。下面我们就一个例子来说明这个问题。

4.4.2.2    一个Session例子:

我们在Global.asax中加上一个Session_Start方法,在里面定义响应的属性:

 

Sub Session_Start(Sender As Object, E As EventArgs)

          Session("name") = "saidy"

      Session("email") = "saidychan@sina.com"

      Session("tel") = "130000121553"

 End Sub

 

赋予属性一个初始值,这样当我们在调用页面(session.aspx)装入时直接就用这些默认值:

      

  <script language="VB" runat="server">

      '返回Session值方法:

      Function getinfo(Key As String) As String

        Return Session(Key).ToString()

      End Function

  </script>&