简介:这是一套面向高校计算机专业学生的《ASP.NET Web 程序设计》第二版配套教学课件,适用于课堂教学、期末复习与自学入门,帮助读者系统建立从 Web 基础到 ASP.NET 开发的完整知识框架。压缩包内共 1 个文件,为 PPT 格式电子讲义,体积约 4.2MB,以章节幻灯片的形式呈现整本书的教学内容,方便直接投屏授课或按章翻阅。课件围绕 HTTP 协议请求与响应流程、Web 服务器与 B/S 体系结构、静态网页与动态网页的差异、基于 Web 的三层数据库应用等基础内容展开,并重点对比 ASP 与 ASP.NET 在效率、可重用性和代码量上的区别,讲解 .NET 框架的组成、MS 中间语言、CLR 公共语言运行库与 .NET 类库的作用,还涉及 ASP.NET 程序基本结构、设计目标与开发步骤。目前已有 181 人学习,适合零基础入门者梳理概念脉络,也适合作为教师备课与课堂讲授的现成素材。
1. 从一套 PPT 电子课件反推 ASP.NET 的知识地图
《ASP.NET Web 程序设计》第二版的全套电子课件,表面上看就是一堆按章切好的 .ppt,翻进去才会发现它把 Web 的底层链路铺得比很多新教材都完整:HTTP 请求怎么发出去、Web 服务器怎么响应、静态页和 .aspx 动态页在服务器端分别发生什么、ASP 的解释执行和 ASP.NET 的编译执行差在哪、IIS 装完之后默认站点落在哪个目录。这些恰好是现在被跳过的部分——很多人直接上手 ASP.NET MVC 或 ASP.NET Core 写 Controller,却说不清一次请求从浏览器到数据库再回来中间经过了哪几层。
这份课件的适用场景其实很具体:高校课程的备课与期末复习、计算机专业复试里的 Web 基础问答、以及维护早期 ASP.NET Web Forms 企业级 Web 项目时需要补的背景知识。下面几章按课件本身的推进顺序拆,每个知识点都配一条能自己动手验证的命令或代码,PPT 上给出的结论,自己在机器上跑一遍再确认。
2. HTTP 报文与 B/S 三层结构:课件里最容易囫囵吞枣的一节
2.1 一次 HTTP 请求响应到底交换了什么
课件把 HTTP 说成"浏览器向 Web 服务器发出的搜索某个网页的请求",这个描述方便入门,但动手时会发现请求行里装的远不止路径。常见做法是先用一个能打印完整报文的客户端把请求"拆开看",把浏览器替你做的隐式动作显式地写出来。
# -v 打印完整的请求行/请求头(前缀 >)与响应行/响应头(前缀 <) curl -v -X GET "http://localhost/Default.aspx" \ -H "Host: localhost" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)" \ -H "Accept: text/html,application/xhtml+xml" \ -H "Cookie: ASP.NET_SessionId=abc123"-X GET指定请求方法,-H逐条追加请求头,-v让 curl 不做静默处理。输出里要盯四样东西:响应状态行(200 还是 404、500)、Content-Type(是不是text/html; charset=utf-8)、Content-Length(返回体字节数)、以及Set-Cookie里有没有ASP.NET_SessionId。最后这一项是判断"这个页面是否在服务器端执行"的最直接证据——纯静态 HTML 不会给你发会话 Cookie。
提示:把
Host头改成另一个域名再请求同一台服务器,能直观看到 IIS 是按 Host 头做站点绑定的,这也是同一台机器跑多个 Web 项目的原理。
2.2 静态页与动态页的判定:先看服务器行为,再看扩展名
课件区分静态网页和动态网页用的是扩展名,这没错但不够。静态页的 .html/.htm 代码是设计完成后原样从磁盘读出来发出的,无论谁访问、什么时候访问、以什么方式进入,返回的字节都一样;动态页的 .asp/.aspx 必须先由服务器端执行程序,再把执行结果拼成 HTML 发回浏览器。
| 对比项 | 静态页(.html/.htm) | 动态页(.asp/.aspx) |
|---|---|---|
| 代码存放位置 | 服务器磁盘,原样保存 | 服务器端程序,可能被编译 |
| 是否在服务端执行 | 否 | 是 |
| 返回内容 | 文件本身的字节 | 程序执行结果生成的 HTML |
| 同一 URL 多次访问 | 内容恒定 | 可随会话、参数、时间变化 |
| 常见服务器端技术 | 无 | CGI、PHP、ASP、JSP、ASP.NET |
验证方法不需要写代码,用两次带不同查询字符串的请求做 diff 就够:
# 请求同一个动态页面的两个不同参数,比较返回体 curl -s "http://localhost/Show.aspx?id=1" > a.html curl -s "http://localhost/Show.aspx?id=2" > b.html diff a.html b.html-s关闭进度条,把返回体重定向到文件。如果diff输出为空,说明这个页面要么是静态的,要么服务端代码根本没读Request.QueryString["id"]——后者是初学者最常见的漏写。反过来,如果两次输出有差异,就说明页面确实在服务器端被执行过,这比看扩展名可靠得多。
2.3 三层 B/S 结构与数据回传路径
课件提到的"Browser/Server/Database Server"三层结构,落到代码上就是三段职责分明的链路:浏览器负责输入输出,Web 服务器负责接收处理,数据库服务器负责存取。把这三层和具体实现对应起来,比背概念有用:
| 层次 | 课件中的角色 | 常见实现 |
|---|---|---|
| 第一层 浏览器 | 用户在表单中输入数据并提交 | HTML 表单、JavaScript、POST 请求 |
| 第二层 Web 服务器 | 接收并处理数据,从数据库查询或录入 | IIS + ASP.NET 应用程序 |
| 第三层 数据库服务器 | 存储数据、响应查询 | SQL Server、MySQL 等 |
第二层的典型写法是参数化查询,而不是拼接 SQL 字符串:
// 位于 Web 服务器上的数据访问代码,连接串统一放在 Web.config 里 string connStr = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString; using (var conn = new SqlConnection(connStr)) using (var cmd = new SqlCommand("SELECT Name FROM Users WHERE Id = @id", conn)) { // @id 是占位符,由 ADO.NET 负责转义,避免字符串拼接带来的注入问题 cmd.Parameters.Add("@id", SqlDbType.Int).Value = id; conn.Open(); object name = cmd.ExecuteScalar(); // 返回结果集首行首列 }SqlDbType.Int显式声明参数类型,让数据库能复用执行计划;using保证连接和命令对象在异常时也能释放;ExecuteScalar适合只取一个值的场景。把这些拆开看,就能理解课件为什么强调三层结构——浏览器、Web 服务器、数据库服务器各自只做自己那一段,任何一层出问题都能单独定位。
3. ASP 与 ASP.NET 的执行模型差异:解释、MSIL 与 JIT
3.1 两条完全不同的执行路径
课件用"效率"两个字概括了 ASP 和 ASP.NET 的差别,展开看是两条执行路径。ASP 是脚本编程环境,只能用 VBScript 或 JavaScript 这类非模块化语言写,每次请求都由脚本引擎逐行解释,解释一行执行一行。ASP.NET 建在 .NET Framework 之上,页面在第一次被请求时整体编译成中间语言,之后再执行的是已经优化过的产物,不需要重新走一遍解析。
这个差异带来的实际感受是:ASP.NET 站点的第一次访问会明显偏慢,随后的请求速度抬升。很多人在本地调试时觉得"刚启动卡一下",就是这个编译过程在消耗时间。
3.2 MSIL、CLR 与 JIT:一段代码的两次编译
课件里 MS 中间语言、CLR、JIT 是分开讲的,实际它们是同一条流水线上的三个环节。用命令行工具可以把这条流水线切开看:
# 在 Visual Studio 开发者命令提示符下运行,先编出程序集 csc /target:library /out:Demo.dll Demo.cs # 导出程序集里的中间语言文本,肉眼确认 IL 长什么样 ildasm Demo.dll /out:Demo.il/target:library生成类库而不是可执行程序,/out:Demo.dll指定输出文件名,ildasm是随 .NET SDK 提供的反汇编工具,/out:Demo.il把 IL 写成文本文件。打开 Demo.il 会看到ldstr、call、ret这类指令——它们不是任何 CPU 能直接执行的机器码,可读性差,但已经做过一轮优化。
真正把它变成机器码发生在运行时:CLR 调用 JIT 编译器,把 IL 翻译成本机代码,并做最后的、与当前机器匹配的优化。CLR 同时承担内存管理、垃圾回收和安全性等核心服务,它才是 .NET Framework 的地基。
| 部件 | 职责 |
|---|---|
| MSIL | 高级语言编译后的中间语言,不能直接执行,经过优化 |
| CLR | 执行 IL,提供内存管理、垃圾回收、安全等核心服务 |
| JIT | 运行时把 IL 编译为本机代码并做本地优化 |
| .NET 类库 | 大量可直接调用的功能库,降低复杂功能的实现难度 |
| .NET 语言 | VB.NET、C#、JScript.NET 等可编译为 IL 的语言 |
3.3 CodeBehind:代码与内容分离怎么落地
课件把"可重用性"归为 ASP.NET 相对 ASP 的核心优势,落到文件结构上就是 CodeBehind。ASP 时代 ASP 代码和 HTML 混在一个文件里,任意位置都能插一段逻辑,表面上方便,实际产生大量难读的页面;ASP.NET 把逻辑抽到后台文件,页面只剩标记:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Demo.Default" %> <html><body> <form id="form1" runat="server"> <asp:Label ID="lblMsg" runat="server" /> <asp:Button ID="btnOk" runat="server" Text="提交" OnClick="btnOk_Click" /> </form> </body></html>// Default.aspx.cs —— 只放逻辑,页面标记不与它混写 public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void btnOk_Click(object sender, EventArgs e) { lblMsg.Text = "当前时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } }CodeBehind指向后台文件名,Inherits指向编译后的类全名,两者必须对应,否则页面运行时会抛解析错误。partial声明分部类,把设计器生成的控件字段声明和手写的逻辑合成一个类。OnClick="btnOk_Click"是事件绑定,方法签名必须保持(object sender, EventArgs e)。这套机制就是课件所说"代码和内容的完全分离",也是后面维护老项目时最先要看懂的东西。
3.4 三个维度的对比结论
| 维度 | ASP | ASP.NET |
|---|---|---|
| 语言 | VBScript、JScript 等非模块化语言 | VB.NET、C#、JScript.NET 等模块化语言 |
| 执行方式 | 逐行解释 | 首次编译为 IL,JIT 后本机执行 |
| 代码组织 | 与 HTML 混合,include 只能有限模块化 | 代码与内容分离,CodeBehind |
| 代码量 | 功能基本都要手写 | 常用功能由框架承担,代码量明显减少 |
| 调试 | 缺少强工具支持 | 编译期检查、断点调试 |
| 配置方式 | 多数靠改代码 | 以 Web.config 配置为主 |
课件还列了 ASP.NET 的设计目标:去除对脚本引擎的依赖、减少开发 Web 应用所需的代码量、允许扩展或替代内置功能、用简单配置完成部署、已有的 ASP 代码经较小修改后可复用、提供强调试工具、语言之间不设能力差异、提供 Windows Authentication / Forms Authentication / Microsoft Passport 三种身份确认模型、不要求额外的开发工具、并且尽可能容忍错误。这几条里,配置部署和身份确认模型在后面的 IIS 章节会直接用到。
4. IIS 站点部署实战:绑定、应用程序池与 Web.config
4.1 安装 IIS 与默认站点目录
课件按 Windows XP 的路径写安装步骤:插入安装光盘,打开控制面板的"添加/删除程序",点击左侧"添加/删除 Windows 组件",在向导里勾选"Internet 信息服务(IIS)",完成后系统自动在系统盘建立网站目录,默认是C:\Inetpub\wwwroot。这套路径在今天的系统上已经不适用,等效操作是用命令行开启对应功能:
# Windows 10/11 与 Windows Server 上启用 IIS 及 ASP.NET 4.x 支持 Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-WebServer, IIS-ASPNET45 -AllIIS-WebServerRole是总开关,IIS-WebServer装上静态文件与默认文档处理能力,IIS-ASPNET45负责把 ASP.NET 4.x 的 ISAPI 处理程序注册进 IIS。少装最后一个,.aspx 页面会直接报 404.3。装完确认一下站点状态和默认文档:
Get-Website | Select-Object Name, State, PhysicalPath Get-WebConfigurationProperty -Filter "system.webServer/defaultDocument" -Name files第一条列出站点名、运行状态和物理路径,用来核对默认站点是否指向C:\Inetpub\wwwroot;第二条列出默认文档列表,确认Default.aspx已在其中,否则访问根路径只会看到目录列表或 403.14。
4.2 站点绑定、应用程序池与 CLR 版本
课件只讲到"展开目录树就能看到默认网站",实际部署新项目时,多站点共用一台服务器才是常态,靠端口或主机名区分。核心概念是应用程序池——每个池是一个独立的 w3wp.exe 进程,站点跑在哪个池里决定了它用哪个 .NET 版本、以及某个站点崩溃时会不会连带其他站点。
| 配置项 | 取值示例 | 说明 |
|---|---|---|
| 绑定类型 | http | 也可以用 https,需要先绑证书 |
| 端口 | 8080 | 与已有站点错开,避免端口冲突 |
| 主机名 | demo.local | 留空则按端口区分 |
| 应用程序池 | DemoPool | 独立进程,隔离故障 |
| 托管管道模式 | 集成 / 经典 | 老项目常需切换为经典 |
| .NET CLR 版本 | v4.0 | 与项目目标框架一致 |
# 新建应用程序池并指定运行时版本 New-WebAppPool -Name "DemoPool" Set-ItemProperty IIS:\AppPools\DemoPool -Name managedRuntimeVersion -Value "v4.0" # 创建站点,绑定 8080 端口,指向项目物理目录 New-Website -Name "DemoSite" -Port 8080 ` -PhysicalPath "C:\Inetpub\wwwroot\Demo" ` -ApplicationPool "DemoPool"managedRuntimeVersion设成v4.0表示这个池只加载 .NET 4.x 运行时,写成别的值(比如空值)会走"无托管代码"模式,.aspx 请求找不到处理程序。-PhysicalPath必须是站点根目录,指向 bin 目录会直接 500。
4.3 Web.config 里必须先认识的几个节点
配置集中在 Web.config,这是 ASP.NET 相对 ASP 最省事的地方——改配置不改代码。下面几个节点是每个项目都会碰到的:
<configuration> <connectionStrings> <add name="AppDb" connectionString="Data Source=.;Initial Catalog=Demo;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <!-- 上线必须关闭 debug,否则编译不优化、异常细节外泄 --> <compilation debug="false" targetFramework="4.8" /> <!-- 对应课件提到的身份确认模型之一:Forms 认证 --> <authentication mode="Forms"> <forms loginUrl="~/Login.aspx" timeout="30" /> </authentication> <!-- 控制 ViewState 的完整性与加密 --> <pages enableViewStateMac="true" viewStateEncryptionMode="Always" /> </system.web> </configuration>connectionStrings把连接串从代码里挪出来,换环境只改配置;debug="false"是上线前的必查项;authentication mode对应课件列出的身份确认模型,Forms是自定义登录页最常见的选择,loginUrl指向未登录时的跳转页,timeout单位是分钟。enableViewStateMac与viewStateEncryptionMode控制 ViewState 的完整性校验与加密,如果项目从很老的模板继承下来,这两项可能被显式关掉,务必改回来。
4.4 上线后最常见的几类报错
| 状态码/现象 | 常见原因 | 处理方向 |
|---|---|---|
| 403.14 | 目录浏览被禁且无默认文档 | 补默认文档,或开启目录浏览 |
| 404.3 | 未注册 .aspx 处理程序 | 安装 IIS-ASPNET45 或重新注册 ASP.NET |
| 500.19 | Web.config 节点被锁定或 XML 格式错误 | 检查节点是否允许覆盖、XML 是否闭合 |
| 500.21 | 应用程序池未安装对应 .NET 版本 | 调整 managedRuntimeVersion |
| 500.24 | 托管管道模式与认证方式冲突 | 临时切换为经典模式验证 |
| 页面能开但样式全丢 | 静态文件处理程序未启用 | 确认 StaticFileModule 已安装 |
处理顺序建议从 500.19 开始排查,因为配置文件读不进去时,IIS 根本不会执行你的代码,后面所有报错都可能是假象。
5. 把课件当学习路线用:页面生命周期与 ViewState 的两个验证技巧
课件讲到 ASP.NET 程序基本结构时列了页面、用户控件、服务器控件、应用程序对象,但没展开页面生命周期,这恰恰是后面所有控件事件能正常工作的前提。事件触发顺序大致是 PreInit、Init、InitComplete、PreLoad、Load、控件事件(如按钮 Click)、PreRender、SaveStateComplete、Render、Unload。ViewState 在 SaveStateComplete 之后、Render 之前被序列化进页面的隐藏字段,所以它记录的是"渲染前的最终状态",这是理解回发机制的钥匙。
有两个成本极低的验证动作,做过一次就很难忘。第一,看 ViewState 到底占了多少字节:
# 取回页面,抓出 __VIEWSTATE 隐藏字段的原始内容 curl -s -c cookie.txt "http://localhost:8080/Default.aspx" \ | grep -o '__VIEWSTATE[^>]*' | head -1 | wc -c-c cookie.txt保存会话 Cookie,保证下次请求在同一会话中;grep -o只输出匹配到的片段;wc -c数字节数。把某个只读的 GridView 上加上EnableViewState="false",重新请求同一页,两个字节数的差值就是 ViewState 的真实成本。数据量大的列表页里,这个数字经常大到让人改变设计。
第二,确认 ViewState 的完整性校验和加密确实是开着的。除了前面 Web.config 里的enableViewStateMac与viewStateEncryptionMode,还要注意machineKey:多台服务器做负载均衡时,各机器的自动生成密钥不一致会导致 ViewState 校验失败,表现为随机的"验证视图状态 MAC 失败"。这类问题在老项目扩容时非常典型,解决方式是在所有节点统一显式配置machineKey,而不是关掉校验。
课件的讲义部分适合建立概念框架,PPT 的章节顺序则基本对应了一条可以照做的学习路线:先看 HTTP 与 B/S 结构,再理解编译模型,然后装 IIS 把示例页跑起来,最后用页面生命周期把零散的控件知识串起来。每一章都动手验证一次,比把 PPT 从头背到尾更接近这门课真实想教的东西。
本文还有配套的精品资源,点击获取