ASP.NET 实例开发教程:从零到构建一个完整的 Web 应用
本教程将引导你完成以下步骤:

- 环境准备:搭建开发环境。
- 项目创建:创建你的第一个 ASP.NET Core 项目。
- Hello World:运行并理解项目的基本结构。
- 核心概念:了解 MVC 模式、路由、控制器和视图。
- 实战项目:待办事项列表
- 步骤 1:显示待办事项列表。
- 步骤 2:添加新的待办事项。
- 步骤 3:编辑现有待办事项。
- 步骤 4:删除待办事项。
- 数据持久化:使用 Entity Framework Core 将数据保存到数据库。
- 部署:将你的应用发布到云服务器。
第一步:环境准备
在开始之前,你需要安装以下软件:
-
.NET SDK (Software Development Kit):
- 访问 .NET 官方下载页面。
- 下载并安装最新的 LTS (长期支持) 版本,.NET 6, 7, 或 8,这包含了编译和运行 .NET 应用所需的一切。
- 安装完成后,打开终端(命令提示符或 PowerShell),输入
dotnet --version,如果显示版本号,则安装成功。
-
代码编辑器:
- Visual Studio (推荐):这是功能最强大的 IDE,你可以从 Visual Studio 官网 下载 Visual Studio Community 版本(对个人、开源和学术用户免费)。
- Visual Studio Code:一个轻量级但功能强大的跨平台编辑器,你需要安装 C# 扩展和 .NET SDK,从 VS Code 官网 下载。
第二步:创建你的第一个 ASP.NET Core 项目
我们将使用命令行工具来创建项目,这能让你更好地理解项目结构。

-
打开终端:在你的电脑上打开一个新的终端窗口。
-
创建项目:
- 导航到你想要存放项目的文件夹(
cd Documents/Dev)。 - 运行以下命令:
dotnet new webapp -n MyTodoApp
dotnet new:创建一个新的 .NET 项目。webapp:模板类型,创建一个基于 Razor Pages 的 Web 应用,这是目前 ASP.NET Core 中最推荐、最简单的入门方式。-n MyTodoApp:指定项目的名称为MyTodoApp。
- 导航到你想要存放项目的文件夹(
-
进入项目目录:
cd MyTodoApp
-
运行项目:
dotnet run
终端会显示类似以下信息:
info: Microsoft.Hosting.Lifetime[14] Now listening on: https://localhost:7123 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:5123 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down.这表示你的 Web 服务器已经启动,正在监听本地的 5123 和 7123 端口。
-
查看结果:
- 打开你的浏览器,访问
https://localhost:7123(推荐使用 HTTPS,因为它更安全)。 - 你应该能看到一个默认的 ASP.NET Core 欢迎页面。
- 打开你的浏览器,访问
第三步:Hello World - 理解项目结构
让我们关闭服务器(在终端按 Ctrl+C),并探索一下项目文件夹,使用 Visual Studio 或 VS Code 打开 MyTodoApp 文件夹。
你会看到以下关键文件和文件夹:
MyTodoApp.csproj:项目文件,定义了项目依赖项(如 ASP.NET Core 包)和配置。Program.cs:应用程序的入口点,在这里配置和启动 Web 应用。appsettings.json:应用程序的配置文件,如数据库连接字符串、日志级别等。Properties/launchSettings.json:开发环境的启动配置,定义了不同的启动 profile。wwwroot/:存放静态文件的地方,如 CSS、JavaScript、图片等。Pages/:这是最重要的文件夹! 在 Razor Pages 模型中,所有的页面都存放在这里,每个.cshtml文件代表一个页面,对应的.cshtml.cs文件是处理该页面逻辑的“代码后台”(Code-behind)。
让我们修改一下默认页面,输出 "Hello, ASP.NET!":
-
打开
Pages/Index.cshtml文件。 -
删除里面的所有 HTML 代码,替换为:
@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Hello, ASP.NET! This is my first page.</p> </div> -
保存文件,然后重新运行
dotnet run。 -
刷新浏览器,你会看到更新后的 "Hello, ASP.NET!" 消息。
第四步:核心概念简介
在开始构建项目前,快速了解几个核心概念:
- Razor Pages:我们使用的模型,它将 UI(
.cshtml视图)和逻辑(.cshtml.cs模型)组织在一起,简单直观。 - MVC (Model-View-Controller):另一种更经典的模式,Controller 接收用户请求,调用 Model 处理数据和业务逻辑,然后选择一个 View 来渲染结果,Razor Pages 可以看作是 MVC 的一种简化变体。
- 路由:URL 到页面或操作之间的映射,默认情况下,
Pages/About.cshtml页面会自动响应/About这个 URL。 - 控制器/页面模型:处理 HTTP 请求(如 GET, POST),执行逻辑,并返回响应。
- 视图:负责生成 HTML 页面,展示数据给用户。
- 模型:代表你的应用程序的数据和业务逻辑,一个
TodoItem类。
第五步:实战项目 - 待办事项列表
让我们开始构建一个功能完整的待办事项应用。
步骤 1:显示待办事项列表
目标:在首页显示一个静态的待办事项列表。
-
创建数据模型: 在
Pages文件夹下,创建一个名为Models的新文件夹,在Models文件夹中,创建一个TodoItem.cs文件:// Pages/Models/TodoItem.cs namespace MyTodoApp.Models { public class TodoItem { public int Id { get; set; } public string? Title { get; set; } public bool IsDone { get; set; } } } -
在页面模型中准备数据: 打开
Pages/Index.cshtml.cs文件,修改它以创建并返回一个待办事项列表。// Pages/Index.cshtml.cs using Microsoft.AspNetCore.Mvc.RazorPages; using MyTodoApp.Models; // 引入我们的模型命名空间 namespace MyTodoApp.Pages { public class IndexModel : PageModel { // 为了在视图中访问,我们将其定义为 public public List<TodoItem> TodoItems { get; set; } = new(); // OnGet 方法在页面通过 GET 请求加载时自动调用 public void OnGet() { // 这里我们先创建一些硬编码的假数据 TodoItems = new List<TodoItem> { new TodoItem { Id = 1, Title = "学习 ASP.NET Core", IsDone = true }, new TodoItem { Id = 2, Title = "构建一个待办事项应用", IsDone = false }, new TodoItem { Id = 3, Title = "部署到云端", IsDone = false } }; } } } -
在视图中显示数据: 修改
Pages/Index.cshtml文件,使用foreach循环来渲染待办事项列表。@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">我的待办事项</h1> </div> <ul> @foreach (var item in Model.TodoItems) { <li> @if (item.IsDone) { <s>@item.Title</s> } else { @item.Title } </li> } </ul> -
运行并查看: 运行
dotnet run,刷新浏览器,你应该能看到一个带项目符号的待办事项列表。
步骤 2:添加新的待办事项
目标:通过一个表单,让用户可以添加新的待办事项。
-
修改页面模型以处理 POST 请求:
Index.cshtml.cs需要处理表单提交(这是一个 POST 请求)。// Pages/Index.cshtml.cs (更新后的代码) using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using MyTodoApp.Models; namespace MyTodoApp.Pages { public class IndexModel : PageModel { public List<TodoItem> TodoItems { get; set; } = new(); // OnGet 保持不变 public void OnGet() { TodoItems = new List<TodoItem> { new TodoItem { Id = 1, Title = "学习 ASP.NET Core", IsDone = true }, new TodoItem { Id = 2, Title = "构建一个待办事项应用", IsDone = false }, new TodoItem { Id = 3, Title = "部署到云端", IsDone = false } }; } // 新增一个 OnPost 方法来处理表单提交 public IActionResult OnPostAddItem(string title) { if (!string.IsNullOrEmpty(title)) { // 在真实应用中,这里应该生成唯一的ID int newId = TodoItems.Count + 1; TodoItems.Add(new TodoItem { Id = newId, Title = title, IsDone = false }); } // 重定向回 GET 请求的 Index 页面,防止表单重复提交 return RedirectToPage(); } } } -
在视图中添加表单: 修改
Pages/Index.cshtml,在列表上方添加一个表单。@page @model IndexModel @* ... 其他代码 ... *@ <div class="text-center"> <h1 class="display-4">我的待办事项</h1> </div> <!-- 新增的表单 --> <form method="post"> <div class="input-group mb-3"> <input type="text" name="title" class="form-control" placeholder="输入新的待办事项..." /> <button type="submit" class="btn btn-primary" asp-page-handler="AddItem">添加</button> </div> </form> <ul> @foreach (var item in Model.TodoItems) { <li> @if (item.IsDone) { <s>@item.Title</s> } else { @item.Title } </li> } </ul>method="post":指定这是一个 POST 请求。name="title":输入框的name属性必须与OnPostAddItem方法的参数title匹配。asp-page-handler="AddItem":这是 Razor Pages 的一个特性,它会将请求路由到OnPostAddItem方法。
-
运行并测试: 运行应用,你应该能看到一个输入框,输入内容并点击“添加”按钮,页面会刷新,新的待办事项会出现在列表中。
步骤 3 & 4:编辑和删除待办事项
这两个功能遵循相同的模式:为每个待办事项项添加“编辑”和“删除”按钮,这些按钮会链接到专门的页面或处理程序。
由于篇幅限制,这里我们简要说明实现思路:
-
删除:
- 在
Index.cshtml的每个<li>中,为删除按钮添加一个表单:<form method="post" asp-page-handler="Delete" asp-route-id="@item.Id"> <button type="submit" class="btn btn-sm btn-danger">删除</button> </form> - 在
Index.cshtml.cs中添加处理方法:public IActionResult OnPostDelete(int id) { var itemToDelete = TodoItems.FirstOrDefault(item => item.Id == id); if (itemToDelete != null) { TodoItems.Remove(itemToDelete); } return RedirectToPage(); }
- 在
-
编辑:
- 更推荐的做法是创建一个新页面
Pages/Edit.cshtml和Pages/Edit.cshtml.cs。 - 在
Index.cshtml中,每个待办事项的“编辑”按钮链接到/Edit?id=x。 Edit.cshtml.cs的OnGet方法根据id从列表中找到待办事项,并将其显示在表单中。Edit.cshtml.cs的OnPost方法接收表单提交的数据,更新列表,然后重定向回Index页面。
- 更推荐的做法是创建一个新页面
第六步:数据持久化 - 使用 Entity Framework Core
我们的数据在应用重启后会丢失,为了将数据保存到数据库,我们使用 Entity Framework Core (EF Core),一个强大的对象关系映射工具。
-
安装 EF Core: 在终端中运行:
dotnet add package Microsoft.EntityFrameworkCore.Sqlite dotnet add package Microsoft.EntityFrameworkCore.Design
Sqlite:一个轻量级的文件数据库,非常适合开发。Design:提供设计时工具,用于创建数据库。
-
创建数据库上下文:
DbContext是 EF Core 的核心,它代表你的数据库会话。-
在
Models文件夹下创建TodoDbContext.cs:// Models/TodoDbContext.cs using Microsoft.EntityFrameworkCore; using MyTodoApp.Models; namespace MyTodoApp.Models { public class TodoDbContext : DbContext { // 构造函数,将配置选项传递给基类 DbContext public TodoDbContext(DbContextOptions<TodoDbContext> options) : base(options) { } // DbSet<TodoItem> 表示数据库中的一张表 public DbSet<TodoItem> TodoItems { get; set; } } }
-
-
配置数据库连接:
-
打开
appsettings.json,添加数据库连接字符串:{ "Logging": { /* ... */ }, "AllowedHosts": "*", "ConnectionStrings": { "DefaultConnection": "Data Source=todo.db" } } -
打开
Program.cs,注册DbContext服务:// Program.cs (更新后的代码) using Microsoft.EntityFrameworkCore; // 添加这个 using using MyTodoApp.Models; // 添加这个 using var builder = WebApplication.CreateBuilder(args); // 1. 添加数据库上下文服务 builder.Services.AddDbContext<TodoDbContext>(options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"))); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); // ... 其余代码 ...
-
-
创建和初始化数据库:
- 在终端运行以下命令,EF Core 会根据你的
DbContext和模型自动创建数据库和表结构:dotnet ef migrations add InitialCreate dotnet ef database update
- 这会在你的项目根目录下创建一个
todo.db文件,以及一个Migrations文件夹。
- 在终端运行以下命令,EF Core 会根据你的
-
修改代码以使用数据库: 我们需要修改
Index.cshtml.cs,让它从数据库读取和保存数据,而不是使用内存列表。// Pages/Index.cshtml.cs (更新后的代码) using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; // 添加这个 using using MyTodoApp.Models; namespace MyTodoApp.Pages { public class IndexModel : PageModel { // 注入 TodoDbContext private readonly TodoDbContext _context; public IndexModel(TodoDbContext context) { _context = context; } public List<TodoItem> TodoItems { get; set; } = new(); public async Task OnGetAsync() { // 从数据库异步获取所有待办事项 TodoItems = await _context.TodoItems.ToListAsync(); } public async Task<IActionResult> OnPostAddItemAsync(string title) { if (!string.IsNullOrEmpty(title)) { var newItem = new TodoItem { Title = title, IsDone = false }; _context.TodoItems.Add(newItem); // 添加到上下文 await _context.SaveChangesAsync(); // 保存更改到数据库 } return RedirectToPage(); } public async Task<IActionResult> OnPostDeleteAsync(int id) { var itemToDelete = await _context.TodoItems.FindAsync(id); if (itemToDelete != null) { _context.TodoItems.Remove(itemToDelete); await _context.SaveChangesAsync(); } return RedirectToPage(); } } }- 我们通过构造函数依赖注入的方式获取
TodoDbContext的实例。 - 所有操作都变成了异步 (
async/await),这是与数据库交互的最佳实践。 - 使用
_context.SaveChanges()或_context.SaveChangesAsync()来提交事务。
- 我们通过构造函数依赖注入的方式获取
重新运行应用,你的待办事项数据会被永久保存在 todo.db 文件中,即使重启应用也不会丢失。
第七步:部署
当你的应用开发完成后,可以将其部署到服务器上,让其他人也能访问。
-
发布应用: 在终端中,运行以下命令来创建一个发布文件夹,其中包含所有运行应用所需的文件。
dotnet publish -c Release -o ./publish
-c Release:以发布模式编译,会进行优化。-o ./publish:将输出文件放到publish文件夹中。
-
选择部署目标:
- IIS (Windows Server):将
publish文件夹中的内容复制到你的 Windows Server 上的 IIS 网站目录。 - Azure App Service:这是最简单的方式之一,你可以直接在 Azure 门户中创建一个 Web App,然后使用 Visual Studio 或 Azure CLI 将你的项目发布上去。
- Docker:可以创建一个 Dockerfile,将你的应用容器化,然后部署到任何支持 Docker 的平台(如 Azure Container Instances, AWS ECS)。
- Linux 服务器:使用
dotnet命令行运行你的应用,并使用 Nginx 或 Apache 作为反向代理。
- IIS (Windows Server):将
总结与后续学习
恭喜!你已经成功地从零开始,构建并部署了一个功能完整的 ASP.NET Core Web 应用。
接下来可以学习什么?
- 身份验证和授权:使用 ASP.NET Core Identity 来实现用户登录、注册和权限管理。
- API 开发:学习创建 RESTful API,为你的前端应用(如 React, Vue, Angular)提供后端服务。
- 依赖注入:深入学习 DI 容器的工作原理和最佳实践。
- 测试:学习使用 xUnit 或 NUnit 为你的应用编写单元测试和集成测试。
- 更高级的 EF Core 功能:如关系、迁移、并发处理等。
ASP.NET Core 是一个现代、快速且功能强大的框架,希望这份教程能为你开启激动人心的 Web 开发之旅!
