ASP.NET 官方文档
名词解释
IIS(Internet Information Services)
IIS 是微软开发的一款 Web 服务器软件,用于在 Windows 服务器上托管和提供Web应用程序和服务。它支持 HTTP、HTTPS、FTP、SMTP 等多种协议,主要用于:
- 托管静态网站和动态 Web 应用程序
- 管理和配置 Web 服务器
- 提供安全性、性能和可扩展性支持
.NET
NET(又称为 .NET Framework,.NET Core,.NET 5/6 等)是一个由微软开发的开发平台,支持多种编程语言、库和工具,旨在帮助开发人员构建各种类型的应用程序,包括Web、桌面、移动和云端应用。它的关键组件包括:
- CLR(Common Language Runtime):.NET 应用程序运行时的核心,负责内存管理、线程管理和安全性等。
- 类库(Class Libraries):一组预定义的类和方法,提供各种常用功能,如文件操作、数据库连接、网络通信等。
C#
C# 是一种由微软开发的现代、面向对象的编程语言,主要用于开发基于 .NET 平台的应用程序。C# 语言设计简洁、类型安全,并且支持多种编程范式,包括面向对象编程、泛型编程和函数式编程。
ASP.NET
ASP.NET 是基于 .NET 平台的Web开发框架,用于创建动态 Web 应用程序和 Web 服务。它提供了一组工具和库,帮助开发者快速构建高性能、可扩展的 Web 应用。ASP.NET 包括以下几部分:
- ASP.NET Web Forms:早期的 Web 开发模型,使用事件驱动的编程模型,类似于 Windows Forms 。
- ASP.NET MVC:基于模型-视图-控制器模式的 Web 开发模型,强调分离关注点,便于测试和维护。
- ASP.NET Web API:用于构建 HTTP 服务,可以被各种客户端(如浏览器、移动设备等)调用。
- ASP.NET Core:现代、跨平台的高性能 Web 框架,是对 ASP.NET 的全面升级和重构,支持在 Windows、macOS 和 Linux 上运行。
ASP.NET 与 IIS、.NET 和 C# 的关系:
- ASP.NET 是基于 .NET 平台构建的。
- ASP.NET 应用程序运行在 .NET 的运行时环境(如 .NET Core 或 .NET Framework)上,依赖于 CLR 进行内存管理、安全性等。
- ASP.NET 使用 .NET 提供的丰富类库和 API ,如文件操作、数据库连接、网络通信等。
- ASP.NET 本身是 .NET 平台的一部分,利用 .NET 平台的底层功能和服务来构建Web应用程序。
- C# 是开发 ASP.NET 应用程序的主要编程语言。
- 开发者使用 C# 编写 ASP.NET 应用程序的代码,包括业务逻辑、数据访问、用户界面等。
- ASP.NET 框架充分利用 C# 的语言特性,如面向对象编程、泛型、异步编程等,提高了开发效率和代码质量。
- C# 代码可以通过 ASP.NET 框架与 HTML、CSS、JavaScript 等前端技术集成,构建完整的 Web 应用程序。
- IIS(Internet Information Services)是 ASP.NET 应用程序的主要托管环境。
- IIS 用于托管和管理 ASP.NET 应用程序,处理客户端的 HTTP 请求。
- IIS 提供了多种配置选项,支持应用程序池、站点绑定、认证和授权等功能,增强了 ASP.NET 应用程序的安全性和性能。
- ASP.NET 应用程序在开发完成后,可以通过 IIS 进行部署和发布,使其能够被用户访问。
项目结构
在 IIS 项目中,文件和目录结构对项目的组织和管理非常重要。一个典型的 IIS 托管的ASP.NET项目的目录结构可能如下:
MyAspNetApp/
├── wwwroot/
│ ├── css/
│ ├── js/
│ ├── images/
│ └── lib/
├── App_Data/
├── App_Start/
│ ├── BundleConfig.cs
│ ├── FilterConfig.cs
│ ├── RouteConfig.cs
│ └── WebApiConfig.cs
├── bin/
├── Content/
│ ├── css/
│ ├── images/
│ └── js/
├── Controllers/
│ ├── HomeController.cs
│ └── AccountController.cs
├── Models/
│ ├── AccountViewModels.cs
│ ├── ApplicationDbContext.cs
│ └── IdentityModels.cs
├── Views/
│ ├── Home/
│ │ ├── Index.cshtml
│ │ └── About.cshtml
│ ├── Shared/
│ │ ├── _Layout.cshtml
│ │ └── _ValidationScriptsPartial.cshtml
│ └── Account/
│ ├── Login.cshtml
│ └── Register.cshtml
├── Pages/
│ ├── Index.cshtml
│ └── Privacy.cshtml
├── Areas/
│ └── Admin/
│ ├── Controllers/
│ │ └── AdminController.cs
│ ├── Models/
│ │ └── AdminViewModels.cs
│ └── Views/
│ └── Admin/
│ ├── Index.cshtml
│ └── Settings.cshtml
├── Properties/
│ └── launchSettings.json
├── Migrations/
│ ├── 20210101010101_InitialCreate.cs
│ └── ApplicationDbContextModelSnapshot.cs
├── Logs/
│ └── log.txt
├── web.config
└── appsettings.json
根目录
- wwwroot:包含所有静态文件,如HTML、CSS、JavaScript、图片等。这是Web服务器公开访问的目录。
- css:存放CSS文件。
- js:存放JavaScript文件。
- images:存放图像文件。
- lib:存放第三方库(通常通过包管理器如npm或NuGet获取)。
应用程序目录
- App_Data:存放应用程序数据文件,如数据库文件、XML文件等。这个目录不会被Web服务器直接公开访问。
- App_Start:包含应用程序启动时运行的代码文件,如路由配置、过滤器配置等(通常在ASP.NET MVC中使用)。
- bin:存放编译后的程序集(DLL文件),这些文件包含了应用程序的逻辑和代码。
- Content:存放静态内容,如CSS、图像等(类似于wwwroot目录,但更常用于ASP.NET MVC项目)。
- Controllers:存放控制器类文件,每个控制器负责处理特定的用户请求(通常在ASP.NET MVC和ASP.NET Core中使用)。
- Models:存放模型类文件,这些文件定义了应用程序的数据结构和业务逻辑。
- Views:存放视图文件(如.cshtml文件),这些文件定义了用户界面布局和显示内容(通常在ASP.NET MVC和Razor Pages中使用)。
- Pages:存放Razor Pages文件(.cshtml),用于定义页面内容和逻辑(主要在ASP.NET Core中使用)。
- Shared:存放共享视图(如布局文件、部分视图),这些视图可以在多个地方重用。
- Areas:用于组织大型应用程序,将应用程序分成多个功能区,每个区域有自己的Controllers、Views、Models等。
配置文件
- web.config:应用程序的配置文件,包含了应用程序设置、连接字符串、安全配置等。对于ASP.NET Core应用,这个文件通常比较简单,很多配置移到了appsettings.json中。
- appsettings.json:ASP.NET Core应用程序的配置文件,包含应用程序设置、连接字符串等,支持分层配置(如appsettings.Development.json)。
日志文件
- Logs:存放应用程序运行时生成的日志文件。
其他
- Properties:存放应用程序属性和设置文件(如launchSettings.json,用于调试配置)。
- Migrations:存放Entity Framework数据库迁移文件,跟踪数据库架构的变更。
文件类型
.aspx & .aspx.cs:Web 页面
.aspx
:ASP.NET 页面文件,负责显示内容。浏览器直接访问 ASPX 页面,对应Web 页面,由 IIS 处理成 HTML 内容输出。.aspx.cs
:页面后的代码文件,负责处理服务器端的逻辑和动作,定义在ASPX.CS
文件中。
例如我们定义 Default.aspx
:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MyApp.Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>My ASP.NET Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblMessage" runat="server" Text="Hello, World!"></asp:Label>
</div>
</form>
</body>
</html>
<%@ Page ... %>
指令:Language="C#"
:指定页面使用 C# 作为编程语言。AutoEventWireup="true"
:自动将页面事件与处理程序连接起来。CodeBehind="Default.aspx.cs"
:指定后台代码文件(也就是.aspx.cs
文件)。Inherits="MyApp.Default"
:指定页面的后台代码类(从System.Web.UI.Page
继承)。
<head runat="server">...</head>
:页面头部,包含页面标题等信息。runat="server"
:表示该元素在服务器上运行,允许服务器端代码操作该元素。
<form id="form1" runat="server">...</form>
:服务器端表单,包含页面上的控件。<asp:Label ... />
:ASP.NET 服务器控件,标签控件用于显示文本。ID="lblMessage"
:控件的唯一标识符。runat="server"
:表示该控件在服务器端运行。Text="Hello, World!"
:控件显示的初始文本。
Default.aspx.cs
:
using System;
using System.Web.UI;
namespace MyApp
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblMessage.Text = "Welcome to my ASP.NET page!";
}
}
}
}
-
using System;
和using System.Web.UI;
:引入命名空间,System
提供基本的类和基类定义,System.Web.UI
提供 ASP.NET 服务器控件和页面类。 -
namespace MyApp
:定义命名空间MyApp
,包含所有相关类。 -
public partial class Default : Page
:定义一个部分类Default
,继承自System.Web.UI.Page
。partial
:允许类的定义分布在多个文件中。
-
protected void Page_Load(object sender, EventArgs e)
:页面加载事件处理程序,当页面加载时调用。protected
:访问修饰符,表示该方法对派生类可见。Page_Load
:方法名称,ASP.NET 中页面加载事件的默认名称。object sender
:事件发送者。EventArgs e
:事件参数。
-
if (!IsPostBack)
:检查页面是否是首次加载(而不是回发)。IsPostBack
:ASP.NET 属性,指示页面是否是回发。
-
lblMessage.Text = "Welcome to my ASP.NET page!";
:设置标签控件lblMessage
的文本。lblMessage
:标签控件的 ID。Text
:控件的文本属性。
上述示例代码的工作原理为:
- 初次加载:当用户首次访问
Default.aspx
页面时,页面会执行Page_Load
事件处理程序,检查IsPostBack
属性。如果页面是首次加载(!IsPostBack
),则设置lblMessage
控件的文本为"Welcome to my ASP.NET page!"
。 - 浏览器显示:IIS 处理
Default.aspx
页面,将其转换为 HTML,并将生成的 HTML 发送到客户端浏览器进行显示。 - 回发处理:如果页面是由于某些操作(例如按钮点击)回发的,
Page_Load
事件处理程序会再次执行,但这次IsPostBack
属性为true
,因此不会再次设置lblMessage
控件的文本。
.ascx & .ascx.cs:用户控件
.ascx
:Web 用户控件文件(User Control),用于定义可插入到 ASPX 页面中的控件。头部文件声明为控件文件。.ascx.cs
:用户控件的后台代码文件,负责处理服务器端的逻辑和动作。
例如我们定义 MyControl.ascx
:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="MyApp.MyControl" %>
<div>
<asp:Label ID="lblControlMessage" runat="server" Text="User Control"></asp:Label>
</div>
<%@ Control ... %>
指令:Language="C#"
:指定控件使用 C# 作为编程语言。AutoEventWireup="true"
:自动将控件事件与处理程序连接起来。CodeBehind="MyControl.ascx.cs"
:指定后台代码文件(也就是.ascx.cs
文件)。Inherits="MyApp.MyControl"
:指定控件的后台代码类(从System.Web.UI.UserControl
继承)。
- HTML 结构:
<div>...</div>
:HTML div 元素,用于包裹控件内容。<asp:Label ... />
:ASP.NET 服务器控件,标签控件用于显示文本。ID="lblControlMessage"
:控件的唯一标识符。runat="server"
:表示该控件在服务器端运行。Text="User Control"
:控件显示的初始文本。
MyControl.ascx.cs
:
using System;
using System.Web.UI;
namespace MyApp
{
public partial class MyControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
// 设置标签控件的文本
lblControlMessage.Text = "Hello from User Control!";
}
}
}
-
命名空间和引用:
using System;
和using System.Web.UI;
:引入必要的命名空间,提供 ASP.NET 服务器控件和页面功能。因为用户控件继承自System.Web.UI.UserControl
。
-
类声明:
public partial class MyControl : UserControl
:定义一个名为MyControl
的公共类,继承自System.Web.UI.UserControl
。partial
:允许类的定义分布在多个文件中。
-
Page_Load
方法:protected void Page_Load(object sender, EventArgs e)
:页面加载事件处理程序,当控件所在的页面加载时调用。object sender
:事件发送者。EventArgs e
:事件参数。
-
设置标签控件的文本:
lblControlMessage.Text = "Hello from User Control!";
:设置标签控件lblControlMessage
的文本为"Hello from User Control!"
。
用户控件创建完成后,可以将其插入到一个 ASPX 页面中,以便在页面中重用该控件。例如 Default.aspx
:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MyApp.Default" %>
<%@ Register Src="~/MyControl.ascx" TagPrefix="uc" TagName="MyControl" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>My ASP.NET Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc:MyControl ID="MyControl1" runat="server" />
</div>
</form>
</body>
</html>
-
<%@ Register ... %>
指令:Src="~/MyControl.ascx"
:指定用户控件文件的位置。TagPrefix="uc"
:指定用户控件的标签前缀。TagName="MyControl"
:指定用户控件的标签名称。
-
HTML 结构:
<uc:MyControl ID="MyControl1" runat="server" />
:将用户控件插入到页面中。ID="MyControl1"
:控件的唯一标识符。runat="server"
:表示该控件在服务器端运行。
上述示例代码的工作原理为:
- 定义用户控件:在
MyControl.ascx
文件中定义用户控件的布局和内容,并在MyControl.ascx.cs
文件中定义控件的逻辑。 - 插入用户控件:在需要使用用户控件的 ASPX 页面中,通过
<%@ Register ... %>
指令注册用户控件,并通过自定义标签将其插入到页面中。 - 运行时行为:
- 当 ASPX 页面加载时,用户控件的
Page_Load
方法会被调用,设置标签控件的文本。 - 整个页面包括用户控件的内容将被处理成 HTML 并发送到客户端浏览器进行显示。
- 当 ASPX 页面加载时,用户控件的
通过这种方式,ASP.NET 实现了页面布局和逻辑的模块化和复用,简化了开发和维护。
.asmx & .asmx.cs:Web 服务文件
通俗的讲就是访问一个特定的 URL 就可以调用远程服务台的某个 API 。
.asmx
:Web 服务的定义文件,描述了 Web 服务的基本信息。asmx.cs
:Web 服务的后台代码文件,包含实际的服务方法逻辑。
例如我们定义 MyWebService.asmx
如下:
<%@ WebService Language="C#" Class="MyApp.MyWebService" %>
<%@ WebService ... %>
指令告诉 ASP.NET 在MyWebService.asmx
文件中使用MyApp.MyWebService
类来处理 Web 服务请求。Language="C#"
:指定 Web 服务使用 C# 作为编程语言。Class="MyApp.MyWebService"
:指定实现 Web 服务逻辑的类的全名,包括命名空间。
MyWebService.asmx.cs
:
using System;
using System.Web.Services;
namespace MyApp
{
[WebService(Namespace = "http://myapp.com/")]
public class MyWebService : WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello, World!";
}
}
}
-
命名空间和引用:
using System;
:引用必要的命名空间,提供基本的类和基类定义。using System.Web.Services;
:引用 ASP.NET 提供的 Web 服务命名空间,包含 Web 服务相关的类和属性。
-
类声明:
namespace MyApp
:定义命名空间MyApp
,包含所有相关类。public class MyWebService : WebService
:定义一个名为MyWebService
的公共类,继承自System.Web.Services.WebService
。
-
[WebService]
属性:[WebService(Namespace = "http://myapp.com/")]
:为 Web 服务指定一个 XML 命名空间,用于区分不同的 Web 服务。命名空间通常是一个 URL,但不一定需要指向实际存在的资源。
-
方法声明:
public string HelloWorld()
:定义一个名为HelloWorld
的公共方法,返回类型为string
。[WebMethod]
:指示这个方法是一个 Web 服务方法,客户端可以通过 Web 服务调用它。
-
方法逻辑:
return "Hello, World!";
:该方法简单地返回字符串 “Hello, World!”。
上述代码的整体工作原理为:
- 定义 Web 服务:在
MyWebService.asmx
文件中通过<%@ WebService ... %>
指令指定使用MyApp.MyWebService
类来处理 Web 服务请求。 - 实现 Web 服务:在
MyWebService.asmx.cs
文件中定义具体的服务方法,使用[WebMethod]
属性标识这些方法,使其可以通过 Web 服务调用。 - 运行时行为:
- 当客户端请求
MyWebService.asmx
时,ASP.NET 将请求路由到MyApp.MyWebService
类。 - 客户端可以调用
HelloWorld
方法(http://yourserver/MyWebService.asmx/HelloWorld
),服务器将执行该方法并返回结果。 - 结果通过 SOAP 协议以 XML 格式返回给客户端。
- 当客户端请求
通过这种方式,ASP.NET 实现了服务器端方法的网络调用,使得客户端可以通过 Web 服务接口远程调用这些方法,实现跨平台和分布式应用程序的集成。
.ashx:Web 处理程序
相对于 .asmx
针对某个特定 URL 的处理程序,来说 .ashx
是针对一类 URL 的处理程序。
一般处理程序文件,用于编写 Web 处理程序(Web Handler)。可以理解为不会显示的 ASPX 页面,但效率更高。ASHX 文件专门用于处理 HTTP 请求(HttpRequest)和修改 HTTP 响应(HttpResponse)。
在 web.config
文件中,我们需要配置 IIS 以便识别和处理 .ashx
请求。以下是相关的配置部分:
<configuration>
<system.webServer>
<handlers>
<add name="MyHandler" path="*.ashx" verb="*" type="MyApp.MyHandler, MyAppAssembly" resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
<system.webServer>
:配置 IIS 7 及更高版本的 Web 服务器设置。<handlers>
:定义 HTTP 处理程序,这些处理程序响应特定的请求。<add>
:添加一个新的处理程序配置。name="MyHandler"
:处理程序的名称。path="*.ashx"
:指定匹配的路径模式,这里是所有以.ashx
结尾的请求。verb="*"
:指定处理的 HTTP 事件(如 GET, POST),*
表示处理所有事件。type="MyApp.MyHandler, MyAppAssembly"
:指定处理程序的类型,包括命名空间和程序集名称。这里MyApp.MyHandler
是处理程序类,MyAppAssembly
是该类所在的程序集名称。resourceType="Unspecified"
:资源类型,通常在处理程序配置中使用Unspecified
。
MyHandler.ashx
文件中定义了一个处理 HTTP 请求的类,实现 IHttpHandler
接口。
using System;
using System.Web;
namespace MyApp
{
public class MyHandler : IHttpHandler
{
// 实现 ProcessRequest 方法,该方法是处理 HTTP 请求的核心逻辑
public void ProcessRequest(HttpContext context)
{
// 设置响应的内容类型为纯文本
context.Response.ContentType = "text/plain";
// 向响应写入内容
context.Response.Write("Hello, this is an ASHX handler.");
}
// 指示处理程序是否可以重用
public bool IsReusable
{
get { return false; }
}
}
}
- 命名空间和引用:
using System;
和using System.Web;
:引用必要的命名空间,提供 ASP.NET 处理程序功能。
- 类声明:
public class MyHandler : IHttpHandler
:定义一个名为MyHandler
的公共类,实现IHttpHandler
接口。
ProcessRequest
方法:public void ProcessRequest(HttpContext context)
:这是IHttpHandler
接口中必须实现的方法,用于处理传入的 HTTP 请求。HttpContext context
:提供对当前 HTTP 请求的所有 HTTP 特定的信息,如请求和响应对象。context.Response.ContentType = "text/plain";
:设置 HTTP 响应的内容类型为纯文本 (text/plain
)。context.Response.Write("Hello, this is an ASHX handler.");
:向 HTTP 响应写入字符串内容"Hello, this is an ASHX handler."
。
IsReusable
属性:public bool IsReusable
:这是IHttpHandler
接口中必须实现的属性,指示处理程序是否可以重用。get { return false; }
:返回false
表示该处理程序实例不可重用。每次请求都会创建一个新的处理程序实例。
上述示例代码的工作原理为:
- 配置处理程序:在
web.config
中配置处理程序,使 IIS 能识别并处理以.ashx
结尾的请求,并将这些请求指派给MyApp.MyHandler
类。 - 处理请求:当浏览器或客户端请求
.ashx
文件时,IIS 会将该请求路由到MyHandler
类的ProcessRequest
方法。 - 生成响应:
ProcessRequest
方法被调用,设置响应的内容类型为text/plain
。- 向响应写入
"Hello, this is an ASHX handler."
,这段文本将被发送回客户端。
- 完成请求:处理程序处理完请求后,IIS 将响应发送回客户端,客户端浏览器显示纯文本内容。
这种机制适用于需要处理简单请求且不需要完整页面渲染的场景,如生成动态内容(例如生成图像、提供数据接口)或处理后台任务。通过这种方式,可以提高响应速度和处理效率。
.cs & .dll:代码文件
.cs
:C# 代码文件,通常包含公共类和业务逻辑。.dll
:动态链接库文件,CS 文件编译后的程序集,包含编译后的代码和资源。位于项目的bin
目录。
WebConfig 配置
web.config
是 ASP.NET 应用程序中的重要配置文件,用于定义应用程序的各种配置设置,如数据库连接字符串、安全性设置、自定义错误页面等。每个 ASP.NET 应用程序的根目录通常都有一个 web.config
文件,该文件使用 XML 格式编写。以下是 web.config
文件的详细介绍:
主要功能和用途
- 应用程序设置:用于存储自定义应用程序配置值。
- 连接字符串:用于存储数据库连接字符串。
- 安全配置:定义身份验证和授权设置。
- 错误处理:配置自定义错误页面。
- 模块和处理程序:定义和配置 HTTP 模块和处理程序。
- 调试和编译设置:配置调试和编译选项。
- 缓存设置:配置输出缓存和数据缓存。
- 国际化和本地化设置:配置区域和语言设置。
结构示例
web.config
文件使用 XML 语法,根元素为 <configuration>
。以下是一个基本的 web.config
文件结构示例:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 应用程序设置 -->
<appSettings>
<add key="ApplicationName" value="MyApp" />
<add key="Environment" value="Production" />
<add key="MaxItems" value="100" />
</appSettings>
<!-- 连接字符串 -->
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=myServer;Initial Catalog=myDatabase;User Id=myUser;Password=myPassword;"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<!-- 身份验证配置 -->
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="30" />
</authentication>
<!-- 授权配置 -->
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<!-- 自定义错误页面 -->
<customErrors mode="RemoteOnly" defaultRedirect="~/Errors/GeneralError.aspx">
<error statusCode="404" redirect="~/Errors/NotFound.aspx" />
<error statusCode="500" redirect="~/Errors/InternalError.aspx" />
</customErrors>
<!-- 编译和调试设置 -->
<compilation debug="true" targetFramework="4.7.2">
<assemblies>
<add assembly="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Optimization, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
<!-- HTTP请求验证 -->
<httpRuntime maxRequestLength="4096" executionTimeout="110" requestValidationMode="2.0" />
<!-- 表单身份验证 -->
<membership defaultProvider="SqlProvider">
<providers>
<add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
connectionStringName="DefaultConnection"
applicationName="MyApp"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordFormat="Hashed" />
</providers>
</membership>
<!-- 配置角色管理 -->
<roleManager enabled="true" defaultProvider="SqlRoleProvider">
<providers>
<add name="SqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" />
</providers>
</roleManager>
<!-- 会话状态 -->
<sessionState mode="InProc" timeout="20" />
</system.web>
<system.webServer>
<!-- 模块 -->
<modules>
<add name="CustomModule" type="Namespace.CustomModule, AssemblyName" />
</modules>
<!-- 处理程序 -->
<handlers>
<add name="CustomHandler" path="*.custom" verb="*" type="Namespace.CustomHandler, AssemblyName" resourceType="Unspecified" />
</handlers>
<!-- 压缩配置 -->
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>
<system.caching>
<!-- 缓存配置 -->
<outputCacheSettings>
<outputCacheProfiles>
<add name="Cache1Hour" duration="3600" varyByParam="none" />
<add name="Cache30Minutes" duration="1800" varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</system.caching>
<!-- 国际化和本地化设置 -->
<system.web>
<globalization culture="en-US" uiCulture="en-US" />
</system.web>
<!-- 日志配置 -->
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Logs\myListener.log" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
自定义配置节 (configSections
)
<configuration>
<configSections>
<section name="myCustomSection" type="MyApp.MyCustomSection, MyAppAssembly" />
</configSections>
<myCustomSection>
<add key="customKey" value="customValue" />
</myCustomSection>
</configuration>
- 作用:定义和使用自定义配置节,上面给出示例就是定义了一个名为
myCustomSection
的配置节,并使用了该配置节。 - 示例解释:
name
:自定义配置节的名称。type
:处理该配置节的类型,包括命名空间和程序集名称。key
:自定义配置的键。value
:自定义配置的值。
应用程序设置 (appSettings
)
<appSettings>
<add key="ApplicationName" value="MyApp" />
<add key="Environment" value="Production" />
<add key="MaxItems" value="100" />
</appSettings>
作用:用于存储键值对配置,应用程序可以通过 ConfigurationManager.AppSettings
访问这些设置。
using System;
using System.Configuration; // System.Configuration 命名空间包含了访问配置文件(如 web.config 和 app.config)所需的类。
class Program
{
static void Main()
{
// 访问 ApplicationName 设置
string applicationName = ConfigurationManager.AppSettings["ApplicationName"];
Console.WriteLine($"Application Name: {applicationName}");
// 访问 Environment 设置
string environment = ConfigurationManager.AppSettings["Environment"];
Console.WriteLine($"Environment: {environment}");
// 访问 MaxItems 设置并将其转换为整数
string maxItemsString = ConfigurationManager.AppSettings["MaxItems"];
if (int.TryParse(maxItemsString, out int maxItems))
{
Console.WriteLine($"Max Items: {maxItems}");
}
else
{
Console.WriteLine("Max Items configuration is not a valid integer.");
}
}
}
连接字符串 (connectionStrings
)
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=myServer;Initial Catalog=myDatabase;User Id=myUser;Password=myPassword;"
providerName="System.Data.SqlClient" />
</connectionStrings>
- 作用:存储数据库连接字符串,应用程序可以通过
ConfigurationManager.ConnectionStrings
访问。using System; using System.Configuration; // System.Data 和 System.Data.SqlClient 命名空间包含了与 SQL Server 数据库交互所需的类。 using System.Data; using System.Data.SqlClient; class Program { static void Main() { // 读取连接字符串 string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; // 打印连接字符串 Console.WriteLine("Connection String: " + connectionString); // 使用连接字符串连接数据库 using (SqlConnection connection = new SqlConnection(connectionString)) { try { // 打开数据库连接 connection.Open(); Console.WriteLine("Database connection opened successfully."); // 示例查询 string query = "SELECT TOP 1 * FROM SomeTable"; SqlCommand command = new SqlCommand(query, connection); // 执行查询并读取结果 using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine("Data from database: " + reader[0].ToString()); } } } catch (Exception ex) { // 捕获并显示异常 Console.WriteLine("Error: " + ex.Message); } finally { // 确保数据库连接关闭 connection.Close(); Console.WriteLine("Database connection closed."); } } } }
- 示例解释:
DefaultConnection
:连接字符串的名称。connectionString
:实际的数据库连接字符串。providerName
:数据库提供程序的名称(如System.Data.SqlClient
)。
身份验证 (system.web
-> authentication
)
在 ASP.NET 中,<authentication>
元素用于配置应用程序的身份验证模式。身份验证模式决定了应用程序如何验证用户的身份。常见的身份验证模式包括:
- Windows 身份验证
- Forms 身份验证
- Passport 身份验证
- None 身份验证
Windows 身份验证
Windows 身份验证使用操作系统的身份验证机制来验证用户。适用于内联网应用程序,用户在登录到网络时会自动进行身份验证。
<system.web>
<authentication mode="Windows" />
</system.web>
HttpContext.Current.User.Identity.IsAuthenticated
可以判断是否通过认证。
using System;
using System.Web;
namespace MyApp
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
string username = HttpContext.Current.User.Identity.Name;
Response.Write($"Hello, {username}! You are authenticated using Windows Authentication.");
}
else
{
Response.Write("You are not authenticated.");
}
}
}
}
Forms 身份验证
Forms 身份验证通过显示一个登录表单来验证用户。适用于互联网应用程序,用户通过输入用户名和密码进行身份验证。
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="30" />
</authentication>
</system.web>
mode
:身份验证模式,Forms
表示使用表单身份验证。loginUrl
:登录页面的 URL。timeout
:登录会话的超时时间(分钟)。
我们可以定义用户登录界面 Login.aspx
如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Account_Login" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Login</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblMessage" runat="server" ForeColor="Red"></asp:Label>
<asp:TextBox ID="txtUsername" runat="server" Placeholder="Username"></asp:TextBox>
<asp:TextBox ID="txtPassword" runat="server" TextMode="Password" Placeholder="Password"></asp:TextBox>
<asp:Button ID="btnLogin" runat="server" Text="Login" OnClick="btnLogin_Click" />
</div>
</form>
</body>
</html>
对应后台处理逻辑 Login.aspx.cs
如下:
using System;
using System.Web;
using System.Web.Security;
public partial class Account_Login : System.Web.UI.Page
{
protected void btnLogin_Click(object sender, EventArgs e)
{
string username = txtUsername.Text;
string password = txtPassword.Text;
// 简化验证用户账号的过程,这里假设用户名和密码为 "admin"
if (username == "admin" && password == "admin")
{
// 创建身份验证票据
FormsAuthenticationTicket ticket = new Forms AuthenticationTicket(
1, // 版本号
username, // 用户名
DateTime.Now, // 票据发出时间
DateTime.Now.AddMinutes(30), // 票据过期时间
false, // 是否持久性
"", // 用户数据
FormsAuthentication.FormsCookiePath // Cookie 路径
);
// 加密票据
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
// 创建身份验证 cookie
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
// 添加 cookie 到响应
Response.Cookies.Add(authCookie);
// 重定向到原始请求页面
string returnUrl = FormsAuthentication.GetRedirectUrl(username, false);
Response.Redirect(returnUrl);
}
else
{
lblMessage.Text = "Invalid username or password.";
}
}
}
此时整个用户登录过程如下:
- 用户访问受保护资源:用户尝试访问受保护的页面或资源,但尚未经过身份验证。
- 重定向到登录页面:由于用户未登录,ASP.NET 会根据
web.config
中的表单身份验证配置,将用户重定向到~/Account/Login
页面。 - 用户登录:用户在
Login.aspx
页面上输入用户名和密码,并提交表单。 - 验证凭据:在
Login.aspx.cs
中,验证用户凭据。如果验证成功,创建并加密身份验证票据,并将其存储在 cookie 中。 - 重定向到原始请求页面:登录成功后,用户被重定向回他们最初请求的受保护资源页面。
Passport 身份验证
Passport 身份验证使用 Microsoft 的 Passport 服务(现已更名为 Microsoft Account)进行身份验证。适用于需要集成 Microsoft 身份验证的应用程序。
<system.web>
<authentication mode="Passport">
<passport redirectUrl="https://login.live.com" />
</authentication>
</system.web>
在后台代码中,通过 HttpContext.User.Identity
获取用户的 Passport 身份信息。
using System;
using System.Web;
namespace MyApp
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
string username = HttpContext.Current.User.Identity.Name;
Response.Write($"Hello, {username}! You are authenticated using Passport Authentication.");
}
else
{
Response.Redirect("https://login.live.com");
}
}
}
}
None 身份验证
None 身份验证模式表示不进行任何身份验证。适用于不需要身份验证的应用程序或仅进行匿名访问的应用程序。
<system.web>
<authentication mode="None" />
</system.web>
授权 (system.web
-> authorization
)
<system.web>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
</system.web>
- 作用:配置用户访问权限。
- 示例解释:
deny users="?"
:拒绝未认证用户的访问。allow users="*"
:允许所有用户访问。
自定义错误页面 (system.web
-> customErrors
)
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="~/Errors/GeneralError.aspx">
<error statusCode="404" redirect="~/Errors/NotFound.aspx" />
<error statusCode="500" redirect="~/Errors/InternalError.aspx" />
</customErrors>
</system.web>
- 作用:配置自定义错误页面。
- 示例解释:
mode
:自定义错误模式,RemoteOnly
表示只有远程请求会看到自定义错误页面。defaultRedirect
:默认错误页面。error
元素:为特定的HTTP状态码配置自定义错误页面。
编译和调试设置 (system.web
-> compilation
)
<system.web>
<compilation debug="true" targetFramework="4.7.2">
<assemblies>
<add assembly="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Optimization, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
</system.web>
- 作用:配置编译选项和调试设置。
- 示例解释:
debug
:是否启用调试模式。targetFramework
:目标框架版本。assemblies
:手动添加的程序集引用。Culture=neutral
:程序集的文化信息,neutral
表示该程序集与任何特定的语言或区域无关。PublicKeyToken=31BF3856AD364E35
:程序集的公钥令牌,用于唯一标识该程序集。
HTTP 请求验证 (system.web
-> httpRuntime
)
<system.web>
<httpRuntime maxRequestLength="4096" executionTimeout="110" requestValidationMode="2.0" />
</system.web>
- 作用:配置请求验证和运行时设置。
- 示例解释:
maxRequestLength
:最大请求长度(KB)。executionTimeout
:请求的超时时间(秒)。requestValidationMode
:请求验证模式。
HTTP 处理程序 (system.web
-> httpHandlers
)
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.ashx" type="MyApp.MyHandler, MyAppAssembly" />
</httpHandlers>
</system.web>
</configuration>
- 作用:定义 HTTP 处理程序,用于处理特定类型的 HTTP 请求。
- 示例解释:
verb
:处理的 HTTP 事件(如 GET, POST)。path
:处理的路径模式。type
:处理程序的类型,包含命名空间和程序集名称。
HTTP 模块 (system.web
-> httpModules
)
<configuration>
<system.web>
<httpModules>
<add name="MyModule" type="MyApp.MyModule, MyAppAssembly" />
</httpModules>
</system.web>
</configuration>
- 作用:定义 HTTP 模块,参与 ASP.NET 请求的处理生命周期。
- 示例解释:
name
:模块的名称。type
:模块的类型,包含命名空间和程序集名称。
ASP.NET 请求的处理生命周期事件:
- BeginRequest:请求开始时触发。这是请求生命周期中的第一个事件,适用于初始化任何请求特定的资源或设置。
- AuthenticateRequest:用于对请求进行身份验证。
- AuthorizeRequest:用于对请求进行授权检查。
- ResolveRequestCache:在该阶段,ASP.NET 可以尝试从缓存中获取响应并直接返回,以提高性能。
- AcquireRequestState:获取与当前请求关联的状态信息(例如 Session 状态)。
- PreRequestHandlerExecute:在 ASP.NET 页面或 HTTP 处理程序执行之前触发。
- PostRequestHandlerExecute:在 ASP.NET 页面或 HTTP 处理程序执行之后触发。
- ReleaseRequestState:在请求状态(例如 Session 状态)已更新之后触发。
- UpdateRequestCache:将请求的响应存储在缓存中,以便将来的请求可以直接从缓存中获取。
- EndRequest:请求结束时触发。通常用于清理资源。
下面这个 HTTP 模块示例程序用来计算请求处理时间并显示在网页上。
using System;
using System.Web;
namespace MyApp
{
public class MyModule : IHttpModule
{
public void Init(HttpApplication context)
{
// 订阅 BeginRequest 和 EndRequest 事件
context.BeginRequest += new EventHandler(OnBeginRequest);
context.EndRequest += new EventHandler(OnEndRequest);
}
private void OnBeginRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
context.Items["RequestStartTime"] = DateTime.Now;
}
private void OnEndRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
DateTime startTime = (DateTime)context.Items["RequestStartTime"];
DateTime endTime = DateTime.Now;
TimeSpan duration = endTime - startTime;
// 记录请求处理时间
string message = $"Request for {context.Request.Url} took {duration.TotalMilliseconds} ms";
context.Response.Write($"<!-- {message} -->");
}
public void Dispose()
{
// 清理资源
}
}
}
表单身份验证 (system.web
-> membership
)
<system.web>
<membership defaultProvider="SqlProvider">
<providers>
<add name="SqlProvider" type="System.Web.Security
.SqlMembershipProvider"
connectionStringName="DefaultConnection"
applicationName="MyApp"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordFormat="Hashed" />
</providers>
</membership>
</system.web>
- 作用:配置会员和身份验证提供程序。
- 示例解释:
defaultProvider
:默认的身份验证提供程序。providers
:配置具体的身份验证提供程序。SqlMembershipProvider
:使用 SQL Server 作为会员存储。
角色管理 (system.web
-> roleManager
)
<system.web>
<roleManager enabled="true" defaultProvider="SqlRoleProvider">
<providers>
<add name="SqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" applicationName="MyApp" />
</providers>
</roleManager>
</system.web>
- 作用:配置角色提供程序。
- 示例解释:
enabled
:是否启用角色管理。defaultProvider
:默认的角色提供程序。providers
:配置具体的角色提供程序。name
:提供程序的名称。type
:提供程序的类型,指定具体的类。connectionStringName
:使用的连接字符串名称,指向存储角色数据的数据库。applicationName
:应用程序名称,用于区分不同应用程序的角色数据。
会话状态 (system.web
-> sessionState
)
<system.web>
<sessionState mode="InProc" timeout="20" />
</system.web>
- 作用:配置会话状态管理。
- 示例解释:
mode
:会话状态模式,InProc
表示会话状态存储在进程内。timeout
:会话超时时间(分钟)。
模块 (system.webServer
-> modules
)
<system.webServer>
<modules>
<add name="CustomModule" type="Namespace.CustomModule, AssemblyName" />
</modules>
</system.webServer>
- 作用:配置 HTTP 模块。
- 示例解释:
name
:模块名称。type
:模块的类型,包含命名空间和程序集名称。
处理程序 (system.webServer
-> handlers
)
<system.webServer>
<handlers>
<add name="CustomHandler" path="*.custom" verb="*" type="Namespace.CustomHandler, AssemblyName" resourceType="Unspecified" />
</handlers>
</system.webServer>
- 作用:配置 HTTP 处理程序。
- 示例解释:
name
:处理程序名称。path
:处理的路径模式。verb
:处理的HTTP动词(如GET, POST)。type
:处理程序的类型,包含命名空间和程序集名称。resourceType
:资源类型。
handlers
应用于配置 IIS 7 及更高版本下的 HTTP 处理程序。相比于 httpHandlers
,handlers
的 system.webServer
配置节点提供了更强大的功能,例如处理程序映射、模块配置等。
对于上面的例子,我们可以定义 CustomHandler.cs
来实现对应的处理逻辑。
using System;
using System.Web;
namespace Namespace
{
public class CustomHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string name = context.Request.QueryString["name"] ?? "World";
context.Response.Write($"Hello, {name}! This is a custom handler.");
}
public bool IsReusable => false;
}
}
在浏览器中访问 http://yourserver/MyHandler.ashx?name=sky123
就可以获得如下相应:
Hello, sky123! This is a custom handler.
压缩配置 (system.webServer
-> urlCompression
)
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>
- 作用:配置 URL 压缩。
- 示例解释:
doStaticCompression
:是否压缩静态内容。doDynamicCompression
:是否压缩动态内容。
缓存配置 (system.caching
)
<system.caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Cache1Hour" duration="3600" varyByParam="none" />
<add name="Cache30Minutes" duration="1800" varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</system.caching>
- 作用:配置输出缓存设置。
- 示例解释:
outputCacheProfiles
:定义缓存配置文件。name
:缓存配置文件名称。duration
:缓存持续时间(秒)。varyByParam
:根据参数变化缓存。
国际化和本地化设置 (system.web
-> globalization
)
<system.web>
<globalization culture="en-US" uiCulture="en-US" />
</system.web>
- 作用:配置应用程序的文化和语言设置。
- 示例解释:
culture
:应用程序的文化设置(语言和区域)。uiCulture
:用户界面的文化设置。
日志配置 (system.diagnostics
)
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Logs\myListener.log" />
</listeners>
</trace>
</system.diagnostics>
- 作用:配置日志记录。
- 示例解释:
autoflush
:是否自动刷新日志缓冲区。indentsize
:日志缩进大小。listeners
:定义日志监听器。name
:监听器名称。type
:监听器的类型。initializeData
:日志文件路径。
开发模式
ASP.NET Web Forms
ASP.NET Web Forms 是微软推出的一个基于事件驱动编程模型的 Web 应用程序框架。它允许开发者使用拖放设计和丰富的控件集快速构建动态、数据驱动的 Web 应用程序。ASP.NET Web Forms 在很大程度上隐藏了 HTML 和 HTTP 的复杂性,使得开发者可以使用类似于桌面应用程序开发的方式进行 Web 开发。
为了便于描述,这里假设有 Default.aspx
:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Simple Web Form</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblMessage" runat="server" Text="Hello, World!"></asp:Label>
<asp:Button ID="btnClickMe" runat="server" Text="Click Me" OnClick="btnClickMe_Click" />
</div>
</form>
</body>
</html>
架构
ASP.NET Web Forms 基于以下核心组件和概念:
- 页面 (Page):每个 Web 表单页面都是
System.Web.UI.Page
类的实例。 - 控件 (Control):Web 表单页面包含各种服务器控件,这些控件可以自动将数据绑定到 HTML 元素上。
- 事件驱动模型:Web 表单使用事件驱动模型处理用户交互和操作。
- ViewState:用于在页面回发(PostBack)之间保存页面和控件的状态。
- 生命周期:ASP.NET Web Forms 页面有一个复杂的生命周期,包括初始化、加载、验证、事件处理和呈现等阶段。
页面生命周期
- 页面请求:用户请求页面时,ASP.NET 确定请求是首次请求还是回发(体现在 .NET 内部变量
IsPostBack
)。 - 开始阶段:页面对象初始化,但尚未恢复任何 ViewState。
- 初始化阶段:控件初始化,控件的属性设置为初始值。对应
Page_Init
回调函数。 - 加载阶段:控件的状态从 ViewState 中恢复。对应
Page_Load
回调函数。 - 回发事件处理阶段:处理特定控件的回发事件,例如按钮点击事件。
- 呈现阶段:页面和控件将自己呈现为 HTML。对应
Page_PreRender
回调函数。 - 卸载阶段:页面发送响应到客户端后进行清理。对应
Page_Unload
回调函数。
页面生命周期的处理函数主要定义在 Default.aspx
对应的 Default.aspx.cs
中:
using System;
using System.Web.UI;
public partial class Default : Page
{
protected void Page_Init(object sender, EventArgs e)
{
// 页面初始化
lblMessage.Text += "Page_Init<br>";
}
protected void Page_Load(object sender, EventArgs e)
{
// 页面加载
lblMessage.Text += "Page_Load<br>";
}
protected void btnClickMe_Click(object sender, EventArgs e)
{
// 按钮点击事件
lblMessage.Text = "Button clicked!<br>";
}
protected void Page_PreRender(object sender, EventArgs e)
{
// 页面呈现前
lblMessage.Text += "Page_PreRender<br>";
}
protected void Page_Unload(object sender, EventArgs e)
{
// 页面卸载
// 无法在这里输出内容,因为响应已经发送到客户端
}
}
请求生命周期
请求生命周期涵盖了整个 ASP.NET 应用程序从请求到响应的处理过程。它是应用程序级别的生命周期,定义了所有请求如何被接收、处理和返回。页面生命周期是请求生命周期的一部分,专门处理页面请求。它定义了页面和控件如何初始化、加载、处理用户输入、呈现和卸载。
请求生命周期包含下面几个事件:
- 开始请求(BeginRequest):请求到达服务器,开始处理。
- 认证请求(AuthenticateRequest):对请求进行身份验证。
- 授权请求(AuthorizeRequest):对请求进行授权检查。
- 解析请求缓存(ResolveRequestCache):尝试从缓存中获取响应。
- 获取请求状态(AcquireRequestState):获取与当前请求关联的状态信息(如 Session 状态)。
- 准备请求处理程序执行(PreRequestHandlerExecute):准备执行请求处理程序。
- 执行请求处理程序(ExecuteRequestHandler):执行请求处理程序(如页面或处理程序)。
- 处理请求完成后事件(PostRequestHandlerExecute):请求处理程序执行完毕。
- 释放请求状态(ReleaseRequestState):释放请求状态(如 Session 状态)。
- 更新请求缓存(UpdateRequestCache):将响应存储到缓存中。
- 结束请求(EndRequest):请求处理完成,准备返回响应。
具体事件处理函数实现定义在 Global.asax
中,有如下回调函数:
Application_Init
:在每一个HttpApplication
实例初始化时执行。通常用于设置应用程序范围的配置和资源。Application_Disposed
:在每一个HttpApplication
实例被销毁之前执行。可以用于清理资源。Application_Start
:在应用程序初始化时执行。在 Web 应用程序的生命周期里只执行一次,用于初始化应用程序范围的资源和设置。Application_End
:在应用程序结束时,在最后一个HttpApplication
实例被销毁之后执行。用于清理应用程序范围的资源。Session_Start
:在会话开始时执行。用于初始化会话范围的资源。Session_End
:在会话结束或过期时执行。用于清理会话范围的资源。Application_BeginRequest
:在收到请求时第一个触发的事件。用于初始化请求范围的资源。Application_AuthenticateRequest
:当安全模块已经建立了当前用户的标识后执行。用于自定义身份验证逻辑。Application_AuthorizeRequest
:当安全模块已经验证了当前用户的授权时执行。用于自定义授权逻辑。Application_ResolveRequestCache
:在完成授权以便缓存模块从缓存中提供服务时执行。用于实现自定义的缓存逻辑。Application_AcquireRequestState
:在获取当前请求所关联的当前状态(如 Session)时执行。用于初始化与请求关联的状态。Application_PreRequestHandlerExecute
:在即将把请求发送到处理程序对象(页面或 WebService)之前执行。用于在处理请求之前执行一些操作。Application_PostRequestHandlerExecute
:在处理程序对象工作完成后执行。用于在处理请求之后执行一些操作。Application_ReleaseRequestState
:在 ASP.NET 执行完所有请求处理程序后执行。用于保存请求范围的状态数据。Application_UpdateRequestCache
:在 ASP.NET 执行完处理程序后为了后续的请求而更新响应缓存时执行。用于实现自定义的缓存更新逻辑。Application_EndRequest
:在响应请求时最后一个触发的事件。用于清理请求范围的资源。Application_PreSendRequestHeaders
:在向客户端发送 HTTP 标头之前执行。用于在发送响应之前进行最后的修改。Application_PreSendRequestContent
:在向客户端发送 HTTP 正文之前执行。用于在发送响应正文之前进行最后的修改。Application_Error
:在应用程序中发生未处理的错误时执行。用于全局错误处理。
Global.asax
示例如下:
<%@ Application Language="C#" %>
<script runat="server">
void Application_BeginRequest(object sender, EventArgs e)
{
// 处理请求开始
HttpContext.Current.Response.Write("BeginRequest<br>");
}
void Application_AuthenticateRequest(object sender, EventArgs e)
{
// 处理身份验证
HttpContext.Current.Response.Write("AuthenticateRequest<br>");
}
void Application_AuthorizeRequest(object sender, EventArgs e)
{
// 处理授权
HttpContext.Current.Response.Write("AuthorizeRequest<br>");
}
void Application_EndRequest(object sender, EventArgs e)
{
// 处理请求结束
HttpContext.Current.Response.Write("EndRequest<br>");
}
</script>
ASP.NET MVC
ASP.NET MVC(Model-View-Controller)是微软开发的一种用于构建动态 Web 应用程序的框架,它基于 MVC 设计模式,将应用程序的不同方面(业务逻辑、用户界面和输入控制)分离开来,使得开发和测试更容易。
MVC 架构将应用程序分为三个主要部分:
- 模型(Model):表示应用程序的业务逻辑和数据。
- 视图(View):负责呈现用户界面(UI)。
- 控制器(Controller):处理用户输入并与模型和视图交互。
主要组件
模型(Model)
模型负责应用程序的业务逻辑和数据访问。它与数据库进行交互,处理数据的存储和检索。
示例模型类,这里只是定义了三个成员变量(MyApp/Models/Product/Product.cs
):
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
视图(View)
视图负责呈现模型的数据。它是用户界面的一部分,使用 Razor 语法编写 HTML。
示例视图文件(MyApp/Views/Product/Index.cshtml
):
@model IEnumerable<MyApp.Models.Product>
<!DOCTYPE html>
<html>
<head>
<title>Product List</title>
</head>
<body>
<h1>Products</h1>
<ul>
@foreach (var product in Model)
{
<li>@product.Name - @product.Price</li>
}
</ul>
</body>
</html>
控制器(Controller)
控制器负责处理用户输入,调用模型来处理数据,并返回相应的视图。
示例控制器类(MyApp/Controllers/ProductController.cs
):
using System.Collections.Generic;
using System.Web.Mvc;
using MyApp.Models;
namespace MyApp.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
var products = new List<Product>
{
new Product { Id = 1, Name = "Laptop", Price = 999.99m },
new Product { Id = 2, Name = "Tablet", Price = 499.99m },
new Product { Id = 3, Name = "Smartphone", Price = 299.99m }
};
return View(products);
}
}
}
工作原理
ASP.NET MVC 的工作原理可以分为以下几个步骤:
- 路由:ASP.NET MVC 使用路由来将请求映射到相应的控制器和动作方法。路由是在
MyApp\App_Start\RouteConfig.cs
中定义的。public class RouteConfig { // 此方法用于注册应用程序中的路由 public static void RegisterRoutes(RouteCollection routes) { // 忽略特定资源的路由,例如 Web 资源(.axd 文件) routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 定义默认路由规则 routes.MapRoute( name: "Default", // 路由名称 url: "{controller}/{action}/{id}", // URL 模式 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 默认参数值 ); } }
Global.asax
文件用于应用程序级别的配置,如路由注册。public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
- 控制器:路由系统将请求转发给相应的控制器。控制器处理请求并与模型交互来获取数据。
- 模型:控制器调用模型来处理业务逻辑和数据访问。模型返回处理后的数据给控制器。
- 视图:控制器将数据传递给视图。视图使用 Razor 语法生成 HTML,并将其返回给浏览器进行呈现。
ASP.NET Core
ASP.NET Core 是一个跨平台、高性能的框架,用于构建现代、云优化的 Web 应用。它是对 ASP.NE T的全面重构,旨在提供更好的性能、更灵活的架构和跨平台支持。ASP.NET Core 具有如下特点:
- 跨平台:可以在 Windows、macOS 和 Linux 上运行。
- 高性能:通过优化的架构和中间件管道提供高性能。
- 模块化和灵活:通过依赖注入和中间件提供高度可定制和模块化的架构。
- 开源:由微软和社区共同开发和维护,在 GitHub 上开源。
- 统一的编程模型:结合了 MVC 和 Web API,简化了开发体验。
项目结构
ASP.NET Core 项目的结构与传统的 ASP.NET 项目有所不同,主要文件和目录包括:
- Program.cs:应用程序的入口点,配置和启动 Web 主机。
- Startup.cs:配置请求管道和服务。
- appsettings.json:应用程序的配置文件。
- Controllers:控制器类,处理 HTTP 请求。
- Models:模型类,表示应用程序的数据和业务逻辑。
- Views:视图文件,用于呈现 HTML 界面。
- wwwroot:静态文件目录,如 CSS、JavaScript 和图片。
MyAspNetCoreApp/
├── Controllers/
│ └── HomeController.cs
├── Models/
│ └── MyModel.cs
├── Views/
│ └── Home/
│ └── Index.cshtml
├── wwwroot/
│ ├── css/
│ ├── js/
│ └── images/
├── appsettings.json
├── Program.cs
└── Startup.cs
Program.cs 和 Startup.cs
Program.cs
文件是应用程序的入口点,负责配置和启动 Web 主机。
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
public class Program
{
// Main 方法是应用程序的入口点,启动 Web 主机。
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
// CreateHostBuilder 方法配置 Web 主机,指定使用 Startup 类进行启动配置。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Startup.cs
文件配置应用程序的服务和中间件。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Startup
{
// ConfigureServices 方法用于注册服务(如 MVC 服务)。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
// Configure 方法用于配置中间件管道,定义请求如何流经应用程序。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
控制器 (Controllers)
控制器类(Controllers/HomeController.cs
)处理 HTTP 请求并返回响应。
using Microsoft.AspNetCore.Mvc;
// 控制器继承自 Controller 基类。
public class HomeController : Controller
{
// 每个方法(如 `Index` 和 `Privacy`)对应一个操作,可以返回视图或其他类型的响应。
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
}
视图 (Views)
视图用于生成 HTML 响应,通常位于 Views
文件夹中,并按照控制器名称组织。
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Welcome to your new ASP.NET Core application.</p>
</div>
模型 (Models)
模型表示应用程序的数据和业务逻辑,通常位于 Models
文件夹中。
public class MyModel
{
public int Id { get; set; }
public string Name { get; set; }
}
中间件 (Middleware)
中间件是 ASP.NET Core 请求处理管道中的组件。每个请求依次通过这些组件进行处理。
在 Startup.cs
的 Configure
方法中配置中间件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
- UseDeveloperExceptionPage:在开发环境中显示详细的错误信息。
- UseExceptionHandler:在生产环境中处理未处理的异常。
- UseHsts:启用 HTTP 严格传输安全。
- UseHttpsRedirection:将 HTTP 请求重定向到 HTTPS。
- UseStaticFiles:提供对静态文件的支持。
- UseRouting:启用路由功能。
- UseAuthorization:启用授权功能。
- UseEndpoints:定义应用程序的终结点和路由模式。
依赖注入 (Dependency Injection)
ASP.NET Core 内置了依赖注入框架,用于管理对象的创建和生命周期。可以在 Startup.cs
的 ConfigureServices
方法中注册服务。
注册服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddScoped<IMyService, MyService>();
}
使用服务:通过构造函数注入服务。
public class HomeController : Controller
{
private readonly IMyService _myService;
public HomeController(IMyService myService)
{
_myService = myService;
}
public IActionResult Index()
{
var data = _myService.GetData();
return View(data);
}
}
配置 (Configuration)
ASP.NET Core 提供了灵活的配置系统,支持从多个源读取配置,如文件、环境变量、命令行参数等。
appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
通过 IConfiguration
接口在应用程序中访问配置:
public class MyService
{
private readonly IConfiguration _configuration;
public MyService(IConfiguration configuration)
{
_configuration = configuration;
}
public void DoSomething()
{
var value = _configuration["MySetting:SubSetting"];
// 使用配置值
}
}
11. 路由 (Routing)
ASP.NET Core 路由系统将请求 URL 映射到特定的处理程序(如控制器和操作方法)。
在 Startup.cs
的 Configure
方法中配置路由:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
通过属性路由定义控制器和操作方法的路由:
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet]
public IActionResult GetAll()
{
// 获取所有产品
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
// 根据 ID 获取产品
}
}
12. 安全性 (Security)
ASP.NET Core 提供了一套完整的安全机制,帮助开发者构建安全的 Web 应用程序。
身份验证和授权
支持多种身份验证方式,如 Cookie、JWT、OAuth 等。
配置身份验证
在 Startup.cs
中配置身份验证:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login";
options.LogoutPath = "/Account/Logout";
});
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdministratorRole", policy =>
policy.RequireRole("Administrator"));
});
services.AddControllersWithViews();
}
在请求管道中启用身份验证和授权中间件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();
app.UseAuthorization();
// 其他中间件
}
数据保护
内置数据保护 API,帮助加密和解密敏感数据。
public class HomeController : Controller
{
private readonly IDataProtector _protector;
public HomeController(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("MyPurposeString");
}
public IActionResult Protect()
{
var plaintext = "Hello World!";
var protectedData = _protector.Protect(plaintext);
var unprotectedData = _protector.Unprotect(protectedData);
return Content($"Original: {plaintext}, Protected: {protectedData}, Unprotected: {unprotectedData}");
}
}
13. 性能优化
ASP.NET Core 提供了多种性能优化技术,确保应用程序的高性能。
响应缓存
通过响应缓存中间件实现响应缓存。
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCaching();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCaching();
// 其他中间件
}
内存缓存和分布式缓存
通过内存缓存和分布式缓存提高应用程序性能。
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost:6379";
options.InstanceName = "SampleInstance";
});
}
使用缓存:
public class HomeController : Controller
{
private readonly IMemoryCache _memoryCache;
private readonly IDistributedCache _distributedCache;
public HomeController(IMemoryCache memoryCache, IDistributedCache distributedCache)
{
_memoryCache = memoryCache;
_distributedCache = distributedCache;
}
public IActionResult CacheExample()
{
// 使用内存缓存
_memoryCache.Set("key", "value");
// 使用分布式缓存
_distributedCache.SetString("key", "value");
return View();
}
}