0 剖析ASP.NET应用程序
用户运行ASP.NET应用程序,不是直接运行,而是使用浏览器(比如IE)通过HTTP请求一个特定的URL(如http://www.mysite.com/mypage.aspx)。这个请求由Web服务器接收。在VS中调试应用程序时,你使用的使本地的测试服务器。而部署应用程序时,使用IIS Web服务器。Web服务器把请求传送给ASP.NET工作者进程,ASP.NET工作者进程会根据虚拟目录把代码的执行隔离到不同的应用程序域。同一个虚拟目录(或它的某个子目录)中的网页在同一个应用程序域中执行。不同的虚拟目录中的网页分别在独立的应用程序域中执行。
ASP.NET应用程序可以包含如下元素:
- Web窗体(.aspx文件)。这是ASP.NET应用程序的基础。
- 母版页(.master文件)。它们是模板,基于它创建的不同Web表单具有相同的结构。
- Web服务(.asmx文件)。它们允许你与其他计算机和其他平台上的应用程序共享有用的功能。
- 代码隐藏文件。根据所使用的代码模型,你还可以有单独的源代码文件。如果使用C#编码,它们具有.cs扩展名。
- 配置文件(.config)。这个文件包含应用程序级别的设置,它配置从安全到调试和状态管理的所有项目。
- global.asax。这个文件包含相应全局应用程序事件的事件处理程序(如应用程序第一次启动时的事件)。
- 其他组件。这些是编译后的程序集,包括由你自己开发或者由第三方开发的具有有用功能的独立组件。通过组件,你可以把业务和数据访问逻辑分离,还可以创建自定义控件。
0.1 应用程序更新
ASP.NET执行模型的一个最出色的特性是你可以随时更新Web应用程序而不必重新启动Web服务器,也不用担心会影响到现有的客户。也就是说,你随时可以往虚拟目录中添加、替换或删除文件。ASP.NET会执行你修改web.config配置文件时的同样动作,切换到一个新应用程序域。
0.2 应用程序目录结构
Bin | 包含ASP.NET Web应用程序使用的所有预编译的.NET程序集(通常是DLL)。这些程序集可以包含预编译的网页类以及这些类引用的其他程序集。 |
App_Code | 包含要在应用程序中使用的动态编译的源代码文件。 |
App_GlobalResources | 这个目录保存可以被Web应用程序里的所有页面访问的全局资源。 |
App_LocalResources | 除了这些资源只能够被专门的页面访问之外,这个目录的作用和App_GlobalResources相同。 |
App_WebReferences | 这个目录保存Web应用程序所使用的对Web服务的引用。包括WSDL文件和发现文档。 |
App_Data | 这个目录用于数据存储,包括SQL Server Express数据库文件以及XML文件。 |
App_Browsers | 包含保存在XML文件里的浏览器定义。这些XML文件为各个程序活动定义客户端浏览器的兼容性。 |
App_Themes | 这个目录保存Web应用程序使用的主题。 |
1 global.asax应用程序文件
global.asax文件允许你编写响应全局事件的事件处理程序。用户不会直接请求global.asax文件。global.asax文件自动执行它的代码来响应特定的应用程序事件。
global.asax文件是可选的,但Web应用程序的global.asax文件不可以多于一个,且它必须位于应用程序的根目录而不位于子目录内。
1.1 应用程序事件
你可以在global.asax文件中处理两类事件。
- 对每次请求都发生的事件。包括与请求相关的和响应相关的事件。
- 只在某些特定情况下才发生的事件。
请求的事件按如下顺序发生。
- Application_BeginRequest()。这个方法在每次请求开始时被调用。
- Application_AuthenticateRequest()。这个方法在执行验证前发生。这是创建你自己的验证逻辑的起点。
- Application_AuthorizeRequest()。发生在用户验证(识别)后,此时应该确定用户的权限。你可以用这个方法给用户赋予特殊的权限。
- Application_ResolveRequestCache()。这个方法常和输出缓存一起使用。
- 在这个时候,请求被转交给合适的处理程序。例如,对于Web窗体的请求,此时应该编译(如有必要)页面并把它实例化。
- Application_AcquireRequestState()。在为客户读取回话特定的信息并把这些信息填充到Session集合前,该方法被调用。
- Application_PreRequestHandlerExecute()。这个方法在合适的HTTP处理程序执行请求前调用。
- 此时,适当的处理程序执行请求。例如,如果是对Web窗体的请求,页面的事件处理程序代码就会被执行,页面呈现为HTML。
- Application_PostRequestHandlerExecute()。这个方法在请求被处理后调用。
- Application_ReleaseRequestState()。这个方法在回话特定信息即将从Session集合序列化时调用,这样它可以用于下一个请求。
- Application_UpdateRequestCache()。这个方法在信息加入到输出缓存前被调用。例如,如果你启用了某个网页的输出缓存,ASP.NET在这个时候把呈现的HTML插入到页面。
- Application_EndRequest()。这个方法在请求结束时但在对象被释放和重新创建前被调用。适合在这时候清理代码。
某些事件并不在每次请求时都发生,如下所示。
- Application_Start()。这个方法在应用程序第一次启动和应用程序域被创建时被调用。这个事件处理程序适合提供应用程序范围的初始化代码。例如,这时候你可以加载和缓存在整个应用程序生命期内不会变化的数据,如导航树、静态的产品列表等。
- Session_Start()。这个方法在每次回话开始时调用。常用于初始化用户特定的信息。
- Application_Error()。这个方法在应用程序发生了未处理的异常时被调用。
- Session_End()。这个方法在用户的会话结束时被调用。会话在你的代码显式释放它或者超过某个指定的时间(一般是20分钟)没有请求后结束。这个方法常用于清理相关的数据。
- Application_End()。这个方法在应用程序结束前被调用。应用程序的结束可能是因为IIS被重新启动或者因为对文件的更新或进程回收导致应用程序切换到一个新的应用程序域。
- Application_Disposed()。这个方法在应用程序被关闭一段时间后并且在.NET垃圾回收器准备收回它占用的内存时被调用。
应用程序事件常用于执行应用程序初始化、清理、使用日志、用户配置以及故障排除。不过,不要假设你的应用程序必须使用全局应用程序事件。很多ASP.NET应用程序根本就不使用global.asax文件。
2 ASP.NET配置
ASP.NET里的配置由XML配置文件管理。配置ASP.NET应用程序的核心设置所需的信息以及应用程序的自定义信息都保存在这些配置文件里。
与传统的ASP配置文件相比,ASP.NET配置文件具有以下优点:
- 它们不会被锁定。你可以在任何时刻更新配置设置,并且ASP.NET会自动平滑地转移到一个新应用程序域。
- 它们方便访问和复制。只要你有合适的网络权限,就可以从远程计算机修改配置文件(甚至通过FTP上传一个新版本)。你还可以复制一个配置文件并将其应用到其他应用程序或者在Web集群环境下运行同一个应用程序的其他Web服务器。
- 它们方便编辑和理解。配置文件里的设置是可读的,也就是说,不必借助任何特殊的配置工具,它们就可以被人编辑和理解。
主要的配置文件由machine.config和web.config。
3 .NET组件
用ASP.NET编写的设计良好的Web应用程序通常会包含单独的组件,它们用于区分数据层和业务层。创建这些组件后,就可以从ASP.NET网页无缝地使用它们了。
创建组件的方式有两种:
- 在App_Code子目录中创建一个新的.cs文件。
- 在VS里创建一个新的类库项目。
虽然这两种方式在本质上相同,但它们对代码的管理却很不相同。当你希望在多个web应用程序里面重用组件时尤为如此。如果采用App_Code方式,很容易做一些轻微的修改从而导致共享类版本的混乱。第二种方式更适合一个开发团队开发大型应用程序,这种情况下,你会希望能够自由地独立完成并编译web应用程序的不同部分。由于这些原因,类库的方式通常为专业的应用程序所采用。(App_Code子目录应该只被用于和web应用程序紧密耦合的类。)
参考文献:《ASP.NET 4 高级程序设计》