本章内容
q ASP.NET和.NET Framework
q 理解ASP.NET控件
q 理解ASP.NET页面
q 安装ASP.NET Framework
q 小结
让我们从创建一个简单的ASP.NET页面开始。
注解 关于安装ASP.NET的更多信息,请参见本章的最后一节。
如果使用Visual Web Developer或Visual Studio.NET,那么首先需要新建一个网站。启动Visual Web Developer,在菜单中选择File(文件)→New Web Site(新建网站),弹出新建网站对话框(见图1-1)。在Location(位置)输入框中输入新建网站所在的文件夹,点击OK(确定)按钮。

图1-1 新建网站
新建网站后,就可以为它添加ASP.NET页面了。选择菜单项WebSite(网站)→Add New Item(添加新项)。选择Web Form(Web窗体),并且在Name(名称)输入框中输入FirstPage.aspx,并确认Place Code in Separate File(将代码放在单独文件中)和Select Master Page(选择母版页)两个复选框都没有选中,最后点击Add(添加)按钮新建一个ASP.NET页面(见图1-2)。

图1-2 新建一个ASP.NET页面
代码清单1-1包含了第一个ASP.NET页面的代码。
代码清单1-1 FirstPage.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()
{
lblServerTime.Text = DateTime.Now.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>First Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Welcome to ASP.NET 2.0! The current date and time is:
<asp:Label
id="lblServerTime"
Runat="server" />
</div>
</form>
</body>
</html>
注解 随书附带资源包含示例代码的C#和Visual Basic .NET版。
代码清单1-1所示的ASP.NET页面显示了一个简单的信息及服务器端当前的日期和时间。右键点击页面文件并选择View in Browser(在浏览器中查看),就可以打开一个浏览器查看该页面(见图1-3)。

图1-3 在浏览器中查看FirstPage.aspx
代码清单1-1中的页面是非常简单的一个页面。不过,它展示了一个ASP.NET页面中最基本的元素。这个页面包含一个指令、一个代码声明块和一个页面呈现块。
代码清单1-1的第一行代码包含一个像下面这样的指令:
<%@ Page Language= "C#" %>
页面中的指令通常用一个特殊的字符<%@开始,并用%>结束。指令主要用于提供给编译器编译该页面所需的信息。
比如,代码清单1-1中的指令指定包含在这个页面中的代码为C#代码。这个页面将被C#编译器编译,而不会由其他编译器(如Visual Basic .NET编译器)来编译。
页面的下一部分开始于一个起始标签<script runat= "server">,结束于一个结束标签</script>。<script>标签包含的内容叫代码声明块(code declaration block)。
代码声明块包含页面要用到的所有方法。它包含这个页面的所有函数和子程序。代码清单1-1中只有如下一个叫Page_Load()的子程序:
void Page_Load()
{
lblServerTime.Text = DateTime.Now.ToString();
}
这个子程序把当前日期和时间赋值给页面body中叫做lblServerTime的一个Lable控件的Text属性。
Page_Load()子程序是一个事件处理程序的例子。这个子程序处理Page_Load事件。每个页面的每一次加载,这个子程序都会自动执行,并且把当前的日期和时间赋值给Lable控件。
页面的最后一部分叫做页面呈现块(page render block)。页面呈现块包含所有呈现到浏览器上的内容。在代码清单1-1中,所有页面呈现块的内容都包含在一对开始和结束<html>标签中。
页面呈现块的大部分内容都由一些平常的HTML组成。比如,页面包含标准的HTML标签:<head>和<body>。在代码清单1-1中,代码呈现块中还有两处特殊的地方。
首先,注意页面中有一个如下的<form>标签:
<form id="form1" runat="server">
这是ASP.NET控件的一个例子。因为这个标签包含一个runat="server"属性,所以该标签表示了一个在服务器端执行的ASP.NET控件。
ASP.NET页面通常称为Web Form页面,因为这些页面几乎总是包含一个服务器端表单元素。
在页面呈现块还有一个Label控件,该控件用<asp:Label>标签声明。在代码清单1-1中,Label控件用于显示当前的日期和时间。
控件是ASP.NET Framework的中心。本书中的大部分篇幅都用于描述这些ASP.NET控件的属性和特征。
我们马上会对控件的细节进行更多的讨论,不过,首先还是需要理解.NET Framework。
注解 ASP.NET页面默认兼容XHTML 1.0过渡标准(Transitional Standard),可以看到代码清单1-1中的页面包含一个XHTML 1.0过渡标准的DOCTYPE。关于ASP.NET Framework如何同时遵循XHTML和辅助功能标准,参见我在微软MSDN网站(msdn.microsoft.com)上的文章:Building ASP.NET 2.0 Web Sites Using Web Standards。
1.1 ASP.NET和.NET Framework
ASP.NET是微软.NET Framework的一部分。要构建ASP.NET页面,需要利用.NET Framework的特性。.NET Framework由两部分组成:框架类库(Framework Class Library)和公共语言运行库。
1.1.1 框架类库
.NET Framework包含成千上万能用于构建应用程序的类。框架类库被设计用来使最普通的编程任务更易于完成。下面是框架中的几个类:
q File类——用于表示硬盘中的文件。可以使用File类来检测文件是否存在、新建文件、删除文件和完成更多与文件操作相关的任务。
q Graphics类——用于完成与各种类型图像(比如GIF,PNG,BMP,JPEG图像)相关的工作。Graphics类可用于在一个图像中绘制矩形、弧形、椭圆和其他各种元素。
q Random类——用于生成随机数。
q SmtpClient类——用于发送电子邮件。SmtpClient类可用于发送包含附件和HTML内容的电子邮件。
这里仅举出了框架中的4个类,而.NET Framework包含了差不多13 000个可用于构建应用程序的类。
打开Microsoft .NET Framework SDK文档,展开Class Library(类库参考)节点,可以查看框架中包含的所有的类(见图1-4)。如果你的机器上没有安装SDK文档,那么请参考本章最后一节的内容。
注解 Microsoft .NET Framework 2.0 包含18 619种类型、12 909个类、401 759个公共方法、93 105个公共属性和30 546个公共事件。
框架中的每一个类都可以有属性、方法和事件。属性、方法和事件作为类的成员公开给外界。举个例子,下面是SmtpClient类成员列表的一部分:
q 属性
n Host——电子邮件服务器端的名字或IP地址。
n Port——发送电子邮件时所使用的端口。
q 方法
n Send——同步地发送一个电子邮件。
n SendAsync——异步地发送一个电子邮件。
q 事件
n SendCompleted——当异步发送操作完成时引发。

图1-4 打开Microsoft .NET Framework SDK文档
如果你知道一个类的成员,那么你就知道利用这个类能做的所有事情。比如,SmtpClient类包含Host和Port两个属性,它们用于在发送电子邮件时指定所使用的电子邮件服务器端和端口。
SmtpClient类还有两个用于发送电子邮件的方法:Send()和SendAsync()。Send()方法在它的发送操作完成前阻塞其他的程序执行;SendAsync()方法异步地发送电子邮件。不像Send()方法,SendAsync()方法不必等待检测发送操作是否成功。
最后,SmtpClient类包含一个名为SendCompleted的事件,该事件在一个异步发送操作完成时引发。你可以为SendCompleted事件创建一个事件处理程序,当电子邮件发送成功时显示消息。
代码清单1-2中的页面使用SmtpClient类并调用它的Send()方法来发送一封电子邮件。
代码清单1-2 SendMail.aspx
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Net.Mail" %>
<!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()
{
SmtpClient client = new SmtpClient();
client.Host = "localhost";
client.Port = 25;
client.Send("steve@somewhere", "bob@somewhere.com", "Let's eat lunch!", "Lunch at the Steak
House?");
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Send Mail</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Email sent!
</div>
</form>
</body>
</html>
代码清单1-2中的页面调用SmtpClient的Send()方法来发送一封电子邮件。其中的第一个参数是发信人地址,第二个参数是收信人地址,第三个参数是邮件主题,最后一个参数是电子邮件的正文。
注意 代码清单1-2中的页面使用本地(Local)SMTP服务器端发送电子邮件。如果你的SMTP服务没有启用,那么你会收到一个“存在的连接被远程主机强制关闭”的错误。你可以通过打开Internet Information Services,右键点击Default SMTP Visual Server并选择Start,来启用本地SMTP服务器端。
1. 命名空间
.NET Framework包含差不多13 000个类,这是一个天文数字。如果微软简单地把这些类混杂在一起,那么你永远也找不到任何想要的东西。幸好,微软把框架中的这些类分别放在了不同的命名空间中。
命名空间(namespace)仅仅是一个类别。比如,所有和操作文件系统有关的类都位于System.IO命名空间中,所有处理微软SQL Server数据库的类都位于System.Data.SqlClient命名空间中。
在页面中使用一个类之前,必须先指出这个类所关联的命名空间。有很多种途径来做这件事情。
首先,你可以使用类的命名空间来“完全限定(full qualify)”类名。比如,File类包含在System.IO命名空间中,所以可以使用下面的语句来检测一个文件是否存在:
System.IO.File.Exists("SomeFile.txt")
每次使用类都指定它的命名空间很快就会让你觉得单调乏味(要输入很多字)。第二种方法是导入一个命名空间。
你可以在页面中添加一个<%@ Import %>指令来导入一个命名空间。在代码清单1-2中,因为SmtpClient类是System.Net.Mail命名空间的一部分,所以我们导入了这个命名空间。代码清单1-2中的页面在其开始部分包含下面这样的指令:
<%@ Import Namespace="System.Net.Mail" %>
导入了一个具体的命名空间后,就可以使用这个命名空间中的所有类而不需要完全限定类名。
最后,如果你发现在应用程序的多个页面中都使用一个命名空间,那么你可以配置应用程序中的所有页面以识别这个命名空间。
注解 Web配置文件是一种特殊类型的文件,可以把配置文件加到应用程序中来配置应用程序。这种文件其实是一个XML文件,所以文件中包含的所有标签都是区分大小写的。通过选择WebSite(网站)→Add New Item(添加新项)→Web Configuration File(Web配置文件),可以为应用程序添加一个Web配置文件。第2卷第7章对Web配置文件有更详细的论述。
如果把代码清单1-3中的Web配置文件加入到应用程序中,那么使用System.Net.Mail命名空间中的类就不需要再在页面中导入这个命名空间了。如果把这个Web.config文件包含进项目中,那么代码清单1-2中的<% Import %>指令就可以从页面中移除了。
代码清单1-3 Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<pages>
<namespaces>
<add namespace="System.Net.Mail"/>
</namespaces>
</pages>
</system.web>
</configuration>
不是所有的命名空间都必须导入,ASP.NET Framework提供了可以自由使用的最常用的命名空间,这样的命名空间有:
|
q System q System.Collections q System.Collections.Specialized q System.Configuration q System.Text q System.Text.RegularExpressions q System.Web q System.Web.Caching |
q System.Web.SessionState q System.Web.Security q System.Web.Profile q System.Web.UI q System.Web.UI.WebControls q System.Web.UI.WebControls.WebParts q System.Web.UI.HTMLControls |
默认的命名空间在根Web配置文件的pages元素中列出,这个文件位于下面的路径:
\WINDOWS\Microsoft.NET\Framework\[version]\CONFIG\Web.Config
2. 程序集
程序集(assembly)就是保存.NET Framework中的类所在硬盘上的.dll文件。比如,ASP.NET Framework中的所有的类都位于一个叫做System.Web.dll的程序集中。
更准确地说,程序集是.NET Framework中最基本的部署、安全和版本控件单位。因为程序集能包含多个文件,一个程序集通常称为一个“逻辑的”dll。
注解 .NET Framework(2.0版本)包含51个程序集。
程序集分两类:私有的和共享的。私有的程序集只能用于一个应用程序,而共享的程序集能用于同一个服务器端上的所有应用程序。
共享程序集位于全局程序集缓存(GAC)中。比如,System.Web.dll与其他.NET Framework包含的程序集都在全局程序集缓存中。
注解 全局程序集缓存的物理地址在计算机的\WINDOWS\Assembly目录,这里有\WINDOWS\ Microsoft.NET\Framework\v2.0.50727文件夹中所有程序集的独立的副本。第一套程序集用于运行时,第二套程序集用于编译时。
在应用程序能使用程序集中的类之前,必须为这个程序集添加一个引用。默认情况下,ASP.NET应用程序引用全局程序集缓存中最常用的程序集:
|
q mscorlib.dll q System.dll q System.Configuration.dll q System.Web.dll q System.Data.dll |
q System.Web.Services.dll q System.Xml.dll q System.Drawing.dll q System.EnterpriseServices.dll q System.Web.Mobile.dll |
使用.NET Framework中的任何类,必须做两件事情。第一,应用程序必须引用包含这个类的程序集;第二,应用程序必须导入这个类所关联的命名空间。
大部分情况下,你不必关心引用所需的程序集,因为最常用的程序集已经自动地引用了。但是,如果要使用一个专门的程序集,就必须显式地为程序集添加引用。例如,如果需要使用System.DirectoryServices命名空间中的类与活动目录(Active Directory)进行交互,那么就需要为应用程序添加System.DirectoryServices.dll的引用。
在.NET Framework SDK文档中,每一个类条目都列出了类关联的程序集和命名空间。比如,在文档中查看MessageQueue类,就能发现这个类位于System.Messaging.dll程序集的System.Messaging命名空间。
如果使用Visual Web Developer,那么可以这样来显式地添加一个程序集的引用:选择WebSite(网站)→Add Reference(添加引用),再选择需要添加引用的程序集的名字。代码清单1-4显示的是加入到应用程序中,添加了System.Messaging.dll的引用后的Web配置文件。
代码清单1-4 Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation>
<assemblies>
<add
assembly="System.Messaging, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
</system.web>
</configuration>
如果不喜欢使用Visual Web Developer,那么可以手工创建代码清单1-4中的文件来添加对System. Messaging.dll的引用。
1.1.2 公共语言运行库
.NET Framework的第二部分是公共语言运行库(CLR),用于执行应用程序代码。
当使用像C#和Visual Basic .NET这样的语言编写.NET Framework应用程序时,源代码从不会直接编译成机器码。相反,C#编译器或Visual Basic .NET编译器把代码转换成一种叫MSIL(微软中间语言)的特殊语言。
MSIL非常像一种面向对象的汇编语言。但与传统的汇编语言不同,MSIL不与特定CPU相关。MSIL是一种底层的、平台无关的语言。
当应用程序正式运行时,JITTER(Just-In-Time编译器)把MSIL代码“实时(just-in-time)”编译成机器码。通常情况下,应用程序并不会整个的从MSIL编译成机器码,只有在编译执行中被实际调用的方法才会被编译成机器码。
事实上,.NET Framework只理解一种语言——MSIL,但可以在.NET Framework上使用C#、Visual Basic .NET语言编写应用程序,因为.NET Framework包含能把由这些语言编写的代码编译成MSIL的编译器。
此处,还可以使用下面这些语言在.NET Framework上编写代码:
|
q Ada q Apl q Caml |
q Oberon q PERL q Pascal |
|
q COBOL q Eiffel q Forth q Fortran q JavaScript |
q PHP q Python q RPG q Scheme q Small Talk |
大多数的ASP.NET开发者使用C#或Visual Basic .NET来编写应用程序。上述列表中的大多数其他.NET语言只是理论上的实验品。
从前,如果你想成为一名开发者,就要集中精力在一定程序上精通某种语言。比如,成为一名C++程序员、一名COBOL程序员或一名Visual Basic程序员。
到了.NET Framework时代,掌握一种具体的语言已经变得不是特别重要了。选择哪种语言在.NET Framework上开发很大程度上取决于个人偏好。如果喜欢大小写区分和花括号,那么可以选择C#编程语言;如果懒于关心大小写,也不喜欢写分号,就可以用Visual Basic .NET写代码。
.NET Framework中所有实际起作用的是框架类库。如果你想成为一名优秀的使用微软技术的程序员,那么就需要学习如何使用框架中13 000个类中所包含的方法、属性和事件。从.NET Framework的角度出发,使用这些类的是C#应用程序还是Visual Basic .NET应用程序并不重要。
注解 书中所有示例代码都有C#和Visual Basic .NET两种版本,Visual Basic .NET 代码可以从本书附带的资源中获得。






