十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于C# .NET 10与ASP.NET Core MVC构建图书管理系统全栈实战

基于C# .NET 10与ASP.NET Core MVC构建图书管理系统全栈实战 在实际企业级应用开发中全栈技术栈的选择至关重要它决定了项目的开发效率、维护成本和长期演进能力。对于希望从零开始构建一个完整、现代化 Web 应用的开发者而言将 C#、.NET 10、ASP.NET Core MVC、EF Core、SQL Server 以及 Bootstrap 组合起来是一条非常成熟且高效的路径。这套技术栈不仅提供了从后端到前端的完整解决方案还因其强类型、高性能和丰富的生态系统成为许多中大型项目的首选。本文旨在为新手开发者提供一个清晰、可复现的实战指南。我们将从零开始搭建一个具备完整 CRUD增删改查功能的简易图书管理系统。通过这个项目你将系统性地掌握如何使用 ASP.NET Core MVC 构建 Web 界面使用 EF Core 进行数据建模和持久化连接 SQL Server 数据库并利用 Bootstrap 快速构建响应式前端界面。文章将重点解释每一步背后的设计逻辑和常见陷阱确保你不仅能“跑通”代码更能理解其工作原理为应对更复杂的生产环境需求打下坚实基础。1. 理解技术栈为什么选择这套组合在动手之前理解每个组件的作用和它们如何协同工作比直接敲代码更重要。这能帮助你在遇到问题时快速定位是哪个环节出了差错。1.1 核心组件角色与协作流程这套技术栈形成了一个清晰的分层架构用户界面层 (UI Layer)由ASP.NET Core MVC框架和Bootstrap库负责。MVC 模式将应用分为模型Model、视图View和控制器Controller。控制器处理 HTTP 请求调用业务逻辑并选择视图进行渲染。视图使用 Razor 语法混合 HTML 和 C# 代码并引入 Bootstrap 的 CSS/JS 来构建美观、响应式的页面。业务逻辑与数据访问层 (Business Data Access Layer)由C#编写的业务逻辑和EF Core负责。EF Core 是一个对象关系映射器ORM它允许你使用 C# 类称为实体来操作数据库而无需编写大量的原始 SQL。它将数据库表映射为 C# 对象极大简化了数据操作。数据存储层 (Data Storage Layer)由SQL Server承担。它是一个关系型数据库管理系统负责安全、可靠地存储结构化数据。运行时与框架 (Runtime Framework).NET 10是这一切的运行平台。它提供了跨平台支持、高性能的即时编译JIT或预先编译AOT、垃圾回收以及庞大的基础类库。协作流程可以简化为浏览器发起请求 - ASP.NET Core 路由到对应控制器 - 控制器方法调用服务业务逻辑 - 服务通过 EF Core 上下文与 SQL Server 交互 - 数据返回给控制器 - 控制器将数据填充到视图模型 - 视图使用 Bootstrap 样式渲染为 HTML - 响应返回给浏览器。1.2 环境与工具准备清单开始编码前请确保你的开发环境已就绪。以下是必需和推荐的软件清单组件推荐版本说明验证安装成功的命令.NET SDK10.0.x包含运行时和 CLI 工具是开发的基础。dotnet --version开发 IDEVisual Studio 2022 或 VS CodeVS 功能全面适合 WindowsVS Code 轻量跨平台需安装 C# 扩展。打开 IDE 即可。数据库SQL Server 2022/2019 Express 或 LocalDBExpress 版免费LocalDB 是轻量版适合开发。sqlcmd -S .\SQLEXPRESS -Q SELECT VERSION(需根据实例名调整)数据库管理工具SQL Server Management Studio (SSMS) 或 Azure Data Studio用于直观地管理数据库、执行查询。连接本地数据库实例。代码管理Git版本控制非必需但强烈推荐。git --version浏览器Chrome/Edge/Firefox用于测试和调试前端。-注意如果你在安装 SQL Server 时遇到端口冲突、身份验证模式选择等问题建议在安装过程中选择“默认实例”和“混合模式身份验证”并牢记设置的 sa 密码。对于纯粹的学习和开发使用 LocalDB随 Visual Studio 安装是更简单的方式它无需独立管理服务。2. 从零创建项目与配置基础结构我们将使用 .NET CLI 来创建项目这是最通用和可复现的方式。打开终端如 PowerShell、CMD 或 Bash。2.1 创建解决方案与项目首先创建一个解决方案文件来管理我们的项目。虽然单一项目也可以但使用解决方案是更清晰的做法。# 创建一个名为 BookManagementSystem 的目录并进入 mkdir BookManagementSystem cd BookManagementSystem # 创建解决方案文件 dotnet new sln -n BookManagementSystem # 创建 ASP.NET Core MVC 项目 dotnet new mvc -n BookManagementSystem.Web -f net10.0 # 将项目添加到解决方案中 dotnet sln add BookManagementSystem.Web/BookManagementSystem.Web.csproj执行后你的目录结构应类似于BookManagementSystem/ ├── BookManagementSystem.sln └── BookManagementSystem.Web/ ├── Controllers/ ├── Models/ ├── Views/ ├── wwwroot/ ├── Program.cs ├── appsettings.json └── BookManagementSystem.Web.csproj2.2 配置项目依赖项我们需要为项目添加 EF Core 和 SQL Server 相关的 NuGet 包。编辑BookManagementSystem.Web/BookManagementSystem.Web.csproj文件或通过 CLI 添加。cd BookManagementSystem.Web dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 10.0.0 dotnet add package Microsoft.EntityFrameworkCore.Tools --version 10.0.0 dotnet add package Microsoft.EntityFrameworkCore.Design --version 10.0.0Microsoft.EntityFrameworkCore.SqlServerEF Core 的 SQL Server 数据库提供程序。Microsoft.EntityFrameworkCore.Tools提供dotnet ef命令行工具用于数据库迁移等操作。Microsoft.EntityFrameworkCore.Design设计时支持是运行dotnet ef命令所必需的。添加后你的.csproj文件应包含类似以下的引用ItemGroup PackageReference IncludeMicrosoft.EntityFrameworkCore.SqlServer Version10.0.0 / PackageReference IncludeMicrosoft.EntityFrameworkCore.Tools Version10.0.0 IncludeAssetsruntime; build; native; contentfiles; analyzers; buildtransitive/IncludeAssets PrivateAssetsall/PrivateAssets /PackageReference PackageReference IncludeMicrosoft.EntityFrameworkCore.Design Version10.0.0 IncludeAssetsruntime; build; native; contentfiles; analyzers; buildtransitive/IncludeAssets PrivateAssetsall/PrivateAssets /PackageReference /ItemGroup2.3 配置数据库连接字符串连接字符串告诉应用程序如何连接到数据库。我们将其放在appsettings.json中并根据环境开发、生产进行区分。打开BookManagementSystem.Web/appsettings.json在Logging节点后添加ConnectionStrings节点{ Logging: { LogLevel: { Default: Information, Microsoft.AspNetCore: Warning } }, ConnectionStrings: { DefaultConnection: Server(localdb)\\mssqllocaldb;DatabaseBookManagementDb;Trusted_ConnectionTrue;MultipleActiveResultSetstrue;TrustServerCertificateTrue }, AllowedHosts: * }关键参数解释Server(localdb)\\mssqllocaldb连接到本地 LocalDB 实例。如果你安装的是 SQL Server Express可能需要改为Server.\\SQLEXPRESS。DatabaseBookManagementDb指定要连接的数据库名称。如果不存在EF Core 可以创建它。Trusted_ConnectionTrue使用 Windows 身份验证。如果使用 SQL Server 身份验证需改为User Idsa;Password你的密码;。MultipleActiveResultSetstrue允许在同一连接上执行多个查询提升性能。TrustServerCertificateTrue在开发环境中信任自签名证书避免连接错误。生产环境警告TrustServerCertificateTrue和将密码硬编码在appsettings.json中是不安全的。生产环境应使用 Azure Key Vault、环境变量或安全的配置管理服务并配置有效的 SSL 证书。3. 定义数据模型与创建数据库我们将以“图书”和“作者”两个实体为例演示一对多的关系。3.1 创建实体类Model在Models文件夹下创建两个类Author.cs和Book.cs。Author.csusing System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace BookManagementSystem.Web.Models { public class Author { public int Id { get; set; } // 主键 [Required] [StringLength(100)] [Display(Name 作者姓名)] public string Name { get; set; } string.Empty; [StringLength(500)] [Display(Name 简介)] public string? Bio { get; set; } // 可空属性 // 导航属性一个作者可以有多本书 public ICollectionBook Books { get; set; } new ListBook(); } }Book.csusing System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace BookManagementSystem.Web.Models { public class Book { public int Id { get; set; } // 主键 [Required] [StringLength(200)] [Display(Name 书名)] public string Title { get; set; } string.Empty; [StringLength(1000)] [Display(Name 描述)] public string? Description { get; set; } [Required] [Display(Name 出版日期)] [DataType(DataType.Date)] public DateTime PublishDate { get; set; } [Required] [Range(0, 10000)] [Display(Name 价格)] [Column(TypeName decimal(18, 2))] // 指定数据库中的精确类型 public decimal Price { get; set; } // 外键 [Display(Name 作者)] public int AuthorId { get; set; } // 导航属性一本书属于一个作者 [ForeignKey(nameof(AuthorId))] public Author? Author { get; set; } } }代码解释[Required],[StringLength]是数据注解用于模型验证和生成数据库约束。[Display]为属性提供显示名称在视图中生成更友好的标签。[DataType(DataType.Date)]提示视图引擎渲染日期选择器。[Column(TypeName decimal(18, 2))]是关键配置确保decimal类型在 SQL Server 中映射为精确的十进制数而不是浮点数避免金额计算精度问题。导航属性 (Books,Author) 定义了实体间的关系EF Core 利用它们来加载关联数据。3.2 创建数据库上下文DbContextDbContext 是 EF Core 的核心它代表与数据库的会话用于查询和保存数据。在Models文件夹或新建Data文件夹下创建ApplicationDbContext.cs。using Microsoft.EntityFrameworkCore; namespace BookManagementSystem.Web.Models { public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptionsApplicationDbContext options) : base(options) { } // 将实体类映射到数据库表 public DbSetBook Books { get; set; } public DbSetAuthor Authors { get; set; } // 可选在此处配置模型如设置索引、默认值等替代数据注解 protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 示例为Author的Name字段添加唯一索引 modelBuilder.EntityAuthor() .HasIndex(a a.Name) .IsUnique(); } } }3.3 注册 DbContext 到依赖注入容器打开Program.cs文件在var builder WebApplication.CreateBuilder(args);之后添加服务注册using BookManagementSystem.Web.Models; using Microsoft.EntityFrameworkCore; var builder WebApplication.CreateBuilder(args); // 从配置中读取连接字符串 var connectionString builder.Configuration.GetConnectionString(DefaultConnection); // 注册 ApplicationDbContext并配置使用 SQL Server builder.Services.AddDbContextApplicationDbContext(options options.UseSqlServer(connectionString)); // Add services to the container. builder.Services.AddControllersWithViews(); var app builder.Build(); // ... 其余代码保持不变3.4 生成数据库迁移并更新数据库现在我们将使用 EF Core 的迁移功能根据代码中的模型变化生成 SQL 脚本来创建或更新数据库结构。# 确保终端路径在项目目录 (BookManagementSystem.Web) 下 # 1. 安装 dotnet-ef 工具如果尚未全局安装 # dotnet tool install --global dotnet-ef # 2. 创建初始迁移命名为 InitialCreate dotnet ef migrations add InitialCreate # 3. 将迁移应用到数据库创建或更新表结构 dotnet ef database update执行后发生了什么migrations add命令会在项目下创建一个Migrations文件夹里面包含时间戳_InitialCreate.cs迁移逻辑和ApplicationDbContextModelSnapshot.cs当前模型快照。database update命令会执行迁移在 SQL Server (LocalDB) 中创建名为BookManagementDb的数据库以及Books、Authors表和__EFMigrationsHistory用于追踪已应用的迁移。你可以使用 SSMS 或 Azure Data Studio 连接到(localdb)\mssqllocaldb实例验证数据库和表是否已成功创建。4. 实现 MVC 控制器与视图我们将为Book实体实现完整的 CRUD 功能。ASP.NET Core 的脚手架功能可以快速生成代码但为了理解原理我们手动创建。4.1 创建 BooksController在Controllers文件夹下创建BooksController.cs。using BookManagementSystem.Web.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; namespace BookManagementSystem.Web.Controllers { public class BooksController : Controller { private readonly ApplicationDbContext _context; public BooksController(ApplicationDbContext context) { _context context; } // GET: Books public async TaskIActionResult Index() { // 使用 Include 加载关联的 Author 数据避免 N1 查询 var books await _context.Books.Include(b b.Author).ToListAsync(); return View(books); } // GET: Books/Details/5 public async TaskIActionResult Details(int? id) { if (id null) { return NotFound(); } var book await _context.Books .Include(b b.Author) .FirstOrDefaultAsync(m m.Id id); if (book null) { return NotFound(); } return View(book); } // GET: Books/Create public IActionResult Create() { // 为下拉列表准备作者数据 ViewData[AuthorId] new SelectList(_context.Authors, Id, Name); return View(); } // POST: Books/Create [HttpPost] [ValidateAntiForgeryToken] public async TaskIActionResult Create([Bind(Id,Title,Description,PublishDate,Price,AuthorId)] Book book) { if (ModelState.IsValid) { _context.Add(book); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // 如果模型验证失败重新填充作者下拉列表 ViewData[AuthorId] new SelectList(_context.Authors, Id, Name, book.AuthorId); return View(book); } // GET: Books/Edit/5 public async TaskIActionResult Edit(int? id) { if (id null) { return NotFound(); } var book await _context.Books.FindAsync(id); if (book null) { return NotFound(); } ViewData[AuthorId] new SelectList(_context.Authors, Id, Name, book.AuthorId); return View(book); } // POST: Books/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async TaskIActionResult Edit(int id, [Bind(Id,Title,Description,PublishDate,Price,AuthorId)] Book book) { if (id ! book.Id) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(book); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!BookExists(book.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } ViewData[AuthorId] new SelectList(_context.Authors, Id, Name, book.AuthorId); return View(book); } // GET: Books/Delete/5 public async TaskIActionResult Delete(int? id) { if (id null) { return NotFound(); } var book await _context.Books .Include(b b.Author) .FirstOrDefaultAsync(m m.Id id); if (book null) { return NotFound(); } return View(book); } // POST: Books/Delete/5 [HttpPost, ActionName(Delete)] [ValidateAntiForgeryToken] public async TaskIActionResult DeleteConfirmed(int id) { var book await _context.Books.FindAsync(id); if (book ! null) { _context.Books.Remove(book); } await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } private bool BookExists(int id) { return _context.Books.Any(e e.Id id); } } }关键点解析依赖注入控制器通过构造函数接收ApplicationDbContext实例这是 .NET Core 依赖注入的典型用法。异步编程所有数据库操作都使用async/await模式避免阻塞线程提高应用吞吐量。Include方法在Index和Details中使用了.Include(b b.Author)这在 EF Core 中称为“贪婪加载”。如果不加在视图中访问book.Author.Name时会触发额外的查询N1 问题严重影响性能。[ValidateAntiForgeryToken]此属性与视图中的Html.AntiForgeryToken()配合用于防止跨站请求伪造攻击。ModelState.IsValid检查通过数据注解定义的模型验证规则是否通过。4.2 创建对应的视图在Views文件夹下创建Books子文件夹然后为每个 Action 创建对应的.cshtml视图文件。这里以Index.cshtml和Create.cshtml为例。Views/Books/Index.cshtmlmodel IEnumerableBookManagementSystem.Web.Models.Book { ViewData[Title] 图书列表; } h1图书列表/h1 p a asp-actionCreate classbtn btn-primary创建新图书/a /p table classtable table-striped table-hover thead tr thHtml.DisplayNameFor(model model.Title)/th thHtml.DisplayNameFor(model model.Author)/th thHtml.DisplayNameFor(model model.PublishDate)/th thHtml.DisplayNameFor(model model.Price)/th th操作/th /tr /thead tbody foreach (var item in Model) { tr tdHtml.DisplayFor(modelItem item.Title)/td tdHtml.DisplayFor(modelItem item.Author.Name)/td tdHtml.DisplayFor(modelItem item.PublishDate)/td tdHtml.DisplayFor(modelItem item.Price)/td td a asp-actionEdit asp-route-iditem.Id classbtn btn-sm btn-outline-warning编辑/a a asp-actionDetails asp-route-iditem.Id classbtn btn-sm btn-outline-info详情/a a asp-actionDelete asp-route-iditem.Id classbtn btn-sm btn-outline-danger删除/a /td /tr } /tbody /tableViews/Books/Create.cshtmlmodel BookManagementSystem.Web.Models.Book { ViewData[Title] 创建图书; } h1创建图书/h1 hr / div classrow div classcol-md-6 form asp-actionCreate div asp-validation-summaryModelOnly classtext-danger/div div classform-group mb-3 label asp-forTitle classcontrol-label/label input asp-forTitle classform-control / span asp-validation-forTitle classtext-danger/span /div div classform-group mb-3 label asp-forAuthorId classcontrol-label/label select asp-forAuthorId class form-control asp-itemsViewBag.AuthorId option value-- 选择作者 --/option /select span asp-validation-forAuthorId classtext-danger/span /div div classform-group mb-3 label asp-forPublishDate classcontrol-label/label input asp-forPublishDate classform-control / span asp-validation-forPublishDate classtext-danger/span /div div classform-group mb-3 label asp-forPrice classcontrol-label/label input asp-forPrice classform-control / span asp-validation-forPrice classtext-danger/span /div div classform-group mb-3 label asp-forDescription classcontrol-label/label textarea asp-forDescription classform-control rows3/textarea span asp-validation-forDescription classtext-danger/span /div div classform-group input typesubmit value创建 classbtn btn-primary / a asp-actionIndex classbtn btn-secondary返回列表/a /div /form /div /div section Scripts { {await Html.RenderPartialAsync(_ValidationScriptsPartial);} }视图关键点model指定视图的强类型模型。Tag Helpersasp-action,asp-route-id,asp-for,asp-items,asp-validation-for等是 ASP.NET Core 的 Tag Helpers它们在服务器端渲染为正确的 HTML 属性简化了表单和链接的生成。Bootstrap 类table,table-striped,btn,btn-primary,form-control,row,col-md-6等是 Bootstrap 的 CSS 类用于快速美化界面。section Scripts用于引入客户端验证脚本来自_ValidationScriptsPartial。4.3 添加导航菜单为了能访问图书管理页面我们修改共享布局文件Views/Shared/_Layout.cshtml中的导航栏。找到ul classnavbar-nav flex-grow-1部分添加一个菜单项li classnav-item a classnav-link text-dark asp-area asp-controllerBooks asp-actionIndex图书管理/a /li5. 运行与验证5.1 运行应用程序在项目根目录 (BookManagementSystem.Web) 下执行dotnet run或直接在 Visual Studio 中按 F5 运行。应用程序将在https://localhost:5001或http://localhost:5000启动。5.2 功能验证流程访问首页打开浏览器访问https://localhost:5001。你应该能看到默认页面并且导航栏有“图书管理”链接。测试 CRUD点击“图书管理”进入Books/Index页面此时列表为空。点击“创建新图书”。由于我们没有作者数据表单中的“作者”下拉列表会是空的。这是一个需要先处理的依赖问题。先创建作者我们需要先实现简单的作者管理或者通过数据库工具直接插入数据。为了快速验证我们可以临时修改BooksController的CreateGET 方法如果没有作者则重定向到一个创建作者的页面或者更简单地在Program.cs中使用种子数据。5.3 添加种子数据快速验证为了快速看到效果我们可以在应用启动时如果数据库为空则自动插入一些测试数据。修改Program.cs// ... 在 app.MapControllerRoute() 之后 app.Run() 之前添加 using (var scope app.Services.CreateScope()) { var services scope.ServiceProvider; try { var context services.GetRequiredServiceApplicationDbContext(); // 确保数据库已创建并应用迁移 context.Database.EnsureCreated(); // 调用种子数据初始化方法 SeedData.Initialize(context); } catch (Exception ex) { var logger services.GetRequiredServiceILoggerProgram(); logger.LogError(ex, 初始化种子数据时发生错误。); } } app.Run();然后在Models文件夹下创建SeedData.csnamespace BookManagementSystem.Web.Models { public static class SeedData { public static void Initialize(ApplicationDbContext context) { // 如果数据库中已有作者则不添加 if (context.Authors.Any()) { return; } var authors new Author[] { new Author { Name 刘慈欣, Bio 科幻作家 }, new Author { Name 余华, Bio 当代作家 }, }; context.Authors.AddRange(authors); context.SaveChanges(); // 如果数据库中已有图书则不添加 if (context.Books.Any()) { return; } var books new Book[] { new Book { Title 三体, PublishDate DateTime.Parse(2008-01-01), Price 68.00m, AuthorId authors[0].Id, Description地球往事三部曲之一 }, new Book { Title 活着, PublishDate DateTime.Parse(1993-01-01), Price 39.00m, AuthorId authors[1].Id, Description讲述一个人一生的故事 }, }; context.Books.AddRange(books); context.SaveChanges(); } } }现在重新运行应用 (dotnet run)访问图书管理页面你应该能看到预置的图书列表并且可以正常进行创建、编辑、查看详情和删除操作。6. 常见问题排查与最佳实践6.1 数据库连接失败现象可能原因检查与解决SqlException: Cannot open database ...1. 连接字符串错误。2. 数据库实例未启动。3. 登录失败。1. 检查appsettings.json中的Server和Database名称。2. 对于 LocalDB尝试sqllocaldb info MSSQLLocalDB和sqllocaldb start MSSQLLocalDB。3. 对于 SQL Server Express检查服务是否运行并使用 SSMS 测试连接。A network-related or instance-specific error...SQL Server 服务未启动或实例名不正确。在服务管理器中启动SQL Server (MSSQLSERVER)或SQL Server (SQLEXPRESS)服务。Login failed for user...身份验证模式不匹配。确认连接字符串使用Trusted_ConnectionTrueWindows认证或正确的User Id和PasswordSQL认证。6.2 迁移命令执行失败现象可能原因检查与解决No executable found matching command dotnet-efEF Core 工具未安装。在项目目录下运行dotnet tool install --global dotnet-ef或确保项目文件引用了Microsoft.EntityFrameworkCore.Tools包。Your startup project ... doesnt reference Microsoft.EntityFrameworkCore.Design.设计时包未引用。确保.csproj文件中包含对Microsoft.EntityFrameworkCore.Design的包引用。More than one DbContext was found.项目中有多个 DbContext。使用-c参数指定上下文dotnet ef migrations add InitialCreate -c ApplicationDbContext。6.3 页面显示或功能异常现象可能原因检查与解决页面样式丢失Bootstrap 无效wwwroot下的静态文件未正确提供服务或_Layout.cshtml中 CSS/JS 引用路径错误。检查Program.cs中是否有app.UseStaticFiles()。检查_Layout.cshtml中link和script的href/src是否正确指向lib/bootstrap/dist/或 CDN。下拉列表如作者列表为空控制器中未向 ViewBag/ViewData 传递数据或数据本身为空。检查对应 Action如CreateGET中是否设置了ViewData[AuthorId] new SelectList(...)。检查数据库 Authors 表是否有数据。创建/编辑后数据未保存1. 模型验证失败。2.SaveChangesAsync()未调用或异常被吞没。3. 并发冲突。1. 在视图中添加div asp-validation-summaryAll/div查看所有错误。2. 检查控制器方法中是否有if (ModelState.IsValid)判断并确保SaveChangesAsync()被调用。3. 查看日志或调试捕获DbUpdateConcurrencyException。6.4 针对新手的进阶最佳实践分离关注点将业务逻辑从控制器移到单独的“服务层”Service Layer。控制器应只负责协调 HTTP 请求和响应复杂的业务规则和数据处理应在服务类中完成。使用仓储模式为每个实体或聚合根创建仓储接口和实现将数据访问逻辑进一步抽象使业务层不直接依赖 EF Core提高可测试性。实现软删除生产环境中直接物理删除数据是危险的。可以在实体中添加bool IsDeleted字段并在查询时默认过滤掉已删除的数据使用 EF Core 的全局查询过滤器。分页与排序当数据量变大时ToListAsync()会加载所有数据到内存。务必使用.Skip()和.Take()实现分页并使用.OrderBy()进行排序。输入验证与清理除了数据注解对于复杂验证应实现IValidatableObject接口。对于富文本输入要进行 HTML 编码或使用白名单过滤防止 XSS 攻击。异常处理与日志不要仅依赖开发环境的异常页面。使用try-catch处理已知异常并使用如 Serilog 或 NLog 的日志框架记录异常和关键操作信息到文件或日志系统。配置管理将不同环境开发、测试、生产的连接字符串、API 密钥等敏感信息通过appsettings.{Environment}.json或环境变量来管理切勿提交到代码仓库。7. 扩展方向与下一步学习建议完成这个基础的全栈 CRUD 应用后你可以沿着以下几个方向深化学习前端交互增强学习使用 jQuery 或更现代的 JavaScript 框架如 Vue.js, React与后端 Web API 交互实现无刷新操作Ajax和更丰富的单页应用体验。API 开发创建 Web API 控制器继承自ControllerBase使用[ApiController]特性为移动应用或前端框架提供数据接口。学习 RESTful 设计原则和 Swagger/OpenAPI 文档生成。身份认证与授权集成 ASP.NET Core Identity为应用添加用户注册、登录、角色管理和基于策略的授权功能。自动化测试为你的服务层和控制器编写单元测试使用 xUnit/NUnit 和 Moq和集成测试确保代码质量。部署与 DevOps学习如何将应用发布到 IIS、Azure App Service 或 Docker 容器中。配置 CI/CD 流水线如 GitHub Actions, Azure DevOps实现自动化构建、测试和部署。性能优化学习使用缓存如 Redis、数据库查询优化分析 EF Core 生成的 SQL、异步编程最佳实践以及应用性能监控。这套技术栈的深度和广度足以支撑从个人项目到企业级系统的开发。关键在于理解每个组件的核心思想并在实践中不断迭代和优化你的代码结构。从这个小项目出发逐步引入上述更高级的概念和技术你的全栈开发能力将得到扎实的提升。
返回列表