有关结构化 ASP 应用程序的其他一些提示和技巧,请参阅文章“ASP Conventions”(英文)。
原则 2:设计为在服务下运行
ASP 将在服务下运行。设计 ASP 应用程序时,您马上会面临在桌面应用程序中不会遇到的安全环境和线程问题。在桌面环境中,通常只处理作为交互式用户运行的单线程执行,而且有权访问当前的桌面系统。在“Internet 信息服务 (IIS)”中,模拟不同用户环境的多个客户机线程调用您的应用程序,而且您的应用程序被限于“系统”桌面。
这对您来说意味着什么?请学习 IIS 的安全模式。还要提醒您:仅因为某些东西能在 Visual Basic IDE 下能够正常运行,并不意味着它就能在 ASP 技术中安全运行。Visual Basic IDE 并没有准确地模拟运行时环境。常见的设计错误包括:在 ASP 技术中使用需要用户界面的 .OCX 控件,使用对线程来说不安全的组件,和使用要求特殊的用户上下文的组件。要避免的一个最简单的问题,就是从应用程序中试图访问 HKEY_CURRENT_USER (HKCU) 注册表项(例如,不要调用 Visual Basic 的 GetSetting 和 SaveSetting 函数,它们都依赖于 HKCU)。同样,不要出现需要用户进行人机交互的消息框或其他对话框。
以下文章是有关 ASP 技术中的安全和验证问题的相当不错的入门读物:
“Authentication and Security for Internet Developers”(英文)
“Q172925 INFO: Security Issues with Objects in ASP and ISAPI Extensions”(英文)
原则 3:封装业务逻辑
ASP 技术通过生成 HTML 输出提供了表示服务。简而言之,它会生成用户界面。您需要将商务逻辑从 ASP 表示脚本中分隔开来。即使您不使用 COM 组件将业务逻辑从 ASP 代码中分隔开来,至少也要将业务逻辑分隔到函数和 include 文件中,以提高可维护性、可读性和可重用性。在需要排除故障和隔离问题时,您还能体会模块化设计方法的好处。
调用脚本内部调用函数和方法,可避免代码乱作一团,并能在 ASP 应用程序中添加结构。下面举例说明从 ASP 代码中,将逻辑分离到方法调用中:
lt;% Main()
MyBizMethod()
...
Sub Main()
GetData()
DisplayData()
End Sub
%>
在使用包含 ASP 功能的技术时,可以应用这一原则。下面举一个使用 Visual Basic WebClass 时的例子,说明如何使用这一原则:
有关共用 ADO 的详细信息,请参阅“Pooling in Microsoft Data Access Components”(英文)。
原则 5:使用数据库维护复杂的状态
尽管 HTTP 协议是无状态的,ASP 开发人员还是会经常使用 ASP 功能内置的状态保持机制。例如,使用 ASP 技术内置的 Application 对象,开发人员所保存的资源能够为应用程序的所有用户共享。通过使用 ASP 内置的 Session 对象,开发人员只为单个用户保存资源。
尽管听起来在 ASP 技术的 Session 对象中保存信息是一个非常方便的保持状态的方式,然而这一方式付出的代价太大,而且它也可能成为对可伸缩性的最大的限制因素之一。应用程序的可伸缩性本质上是随着用户数目的增长能够继续保持其性能的能力。而对于每一用户,在会话超时或被放弃之前,Session 对象都会消耗服务器的资源。会话还会将您捆绑到一台服务器上,从而限制您利用 Web 集群的功能。请尽可能不要使用 ASP Session 对象进行状态管理。如果您完全没有使用会话,您就可以禁用 Web 应用程序的 Session 状态(请参阅 IIS 文档)。否则,您可以使用下述语句,针对每一页禁用 Session 状态:
<%@ENABLESESSIONSTATE=False %>
对于一些简单的数据,您可以使用 QueryString cookie 或隐藏的窗体域保持 ASP 请求间的状态。然后,对于更为复杂的信息,通常推荐您使用数据库。一般所采用的方式是生成某一特有的标识符,然后发送到每一个发出请求的客户机,并保存为隐藏的窗体域。在随后的请求中,这一特有的标识符被用于在数据库中查找与该用户相关的状态信息。这一方式提供了更高的可伸缩性和更为简洁明了的代码。
有关使用 QueryString cookie 和隐藏的窗体域的详细信息,请参阅“Q175167 HOWTO: Persisting values Without Sessions”(英文)。