news 2026/6/13 14:27:52

3-从零搭建 模块化分层架构 .NET 8 报修系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
3-从零搭建 模块化分层架构 .NET 8 报修系统

整体架构:4个项目+ 标准分层 + 接口解耦 + 模块化,适配EF Core / Dapper / JWT / 过滤器 / 中间件 / RabbitMQ / RESTful / 路由,易维护、可扩展。

一、整体架构回顾(最终结构)

项目组成(一共 4 个项目,全部 .NET 8)

  1. DeviceRepair.Api(WebAPI 启动项目 / 表现层) 控制器、路由、过滤器、中间件、Swagger、管道配置

  2. DeviceRepair.Core(核心类库,底层不依赖任何项目) 实体、枚举、DTO、通用返回模型、仓储 / 服务接口

  3. DeviceRepair.Infrastructure(基础设施层) EF 上下文、仓储实现、Dapper、JWT 工具、RabbitMQ、服务注册扩展

  4. DeviceRepair.Services(业务逻辑层) 业务服务实现,按模块拆分

依赖规则(单向依赖,解耦核心)

DeviceRepair.Api → 引用 DeviceRepair.Core → 引用 DeviceRepair.Services → 引用 DeviceRepair.Infrastructure DeviceRepair.Services → 只引用 DeviceRepair.Core DeviceRepair.Infrastructure → 只引用 DeviceRepair.Core DeviceRepair.Core → 无任何项目引用(最底层)

第一阶段:创建 4 个项目 & 配置引用

1. 打开 Visual Studio 2022

  1. 新建空白解决方案,命名:DeviceRepair

  2. 依次创建 4 个项目

项目 1:DeviceRepair.Api(ASP.NET Core Web API)

  • 模板:ASP.NET Core Web API

  • 框架:.NET 8

  • 取消:使用控制器(可选,本文用控制器模式)、取消 HTTPS

  • 名称:DeviceRepair.Api启动项目

项目 2:DeviceRepair.Core(类库)

  • 模板:类库

  • 框架:.NET 8

  • 名称:DeviceRepair.Core

项目 3:DeviceRepair.Infrastructure(类库)

  • 模板:类库

  • 框架:.NET 8

  • 名称:DeviceRepair.Infrastructure

项目 4:DeviceRepair.Services(类库)

  • 模板:类库

  • 框架:.NET 8

  • 名称:DeviceRepair.Services

配置项目引用(必须严格按依赖来)

右键项目 →添加 → 项目引用

  1. DeviceRepair.Api勾选:DeviceRepair.CoreDeviceRepair.ServicesDeviceRepair.Infrastructure

  2. DeviceRepair.Services勾选:DeviceRepair.Core

  3. DeviceRepair.Infrastructure勾选:DeviceRepair.Core

  4. DeviceRepair.Core:不添加任何引用

统一安装 NuGet 包

3.1 DeviceRepair.Core(无需第三方包)

纯模型 / 接口,不装任何 NuGet。

3.2 DeviceRepair.Infrastructure(基础设施,核心第三方包)

右键 → 管理 NuGet 程序包,安装:

Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCore.Tools Dapper Microsoft.AspNetCore.Authentication.JwtBearer Microsoft.Extensions.Configuration
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Dapper" Version="2.1.35" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.17" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.17" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.17" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.17" PrivateAssets="all" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.17" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\DeviceRepair.Core\DeviceRepair.Core.csproj" /> </ItemGroup> </Project>

3.3 DeviceRepair.Services(无需额外包)

3.4 DeviceRepair.Api(WebAPI 基础包)

默认自带,无需额外安装。


开发 DeviceRepair.Core(核心层)

该层存放实体、枚举、DTO、通用返回体、接口,先写完这一层。

1. 新建文件夹结构(Core)

DeviceRepair.Core ├─ Entities # 数据库实体 ├─ Enums # 枚举 ├─ Dtos # 前后端交互入参/出参 ├─ Interfaces # 仓储接口、服务接口 └─ ResultModel.cs # 全局统一返回格式

2. 编写全局统一返回模型ResultModel.cs

namespace DeviceRepair.Core { /// <summary> /// RESTful 统一接口返回格式 /// </summary> public class ResultModel<T> { public int Code { get; set; } public string Msg { get; set; } = string.Empty; public T? Data { get; set; } /// <summary> /// 成功返回 /// </summary> public static ResultModel<T> Success(T? data, string msg = "请求成功") { return new ResultModel<T> { Code = 200, Msg = msg, Data = data }; } /// <summary> /// 失败返回 /// </summary> public static ResultModel<T> Fail(string msg = "请求失败", int code = 400) { return new ResultModel<T> { Code = code, Msg = msg }; } } }

3. Enums 枚举

新建Enums/GlobalEnum.cs

namespace DeviceRepair.Core.Enums { /// <summary> /// 用户角色 /// </summary> public enum UserRole { Staff = 0, // 普通员工 RepairMan = 1, // 维修员 Admin = 2 // 管理员 } /// <summary> /// 工单状态 /// </summary> public enum OrderStatus { WaitAccept = 0, // 待接单 Processing = 1, // 处理中 Finished = 2, // 已完成 Cancel = 3 // 已作废 } }

4. Entities 数据库实体

4.1 User.cs 用户实体

using DeviceRepair.Core.Enums; using System.ComponentModel.DataAnnotations; namespace DeviceRepair.Core.Entities { public class User { public int Id { get; set; } [MaxLength(50)] public string UserName { get; set; } = string.Empty; [MaxLength(50)] public string Password { get; set; } = string.Empty; [MaxLength(50)] public string? RealName { get; set; } public UserRole Role { get; set; } public DateTime CreateTime { get; set; } public bool IsDeleted { get; set; } } }

4.2 Device.cs 设备实体

using System.ComponentModel.DataAnnotations; namespace DeviceRepair.Core.Entities { public class Device { public int Id { get; set; } [MaxLength(100)] public string DeviceName { get; set; } = string.Empty; [MaxLength(50)] public string? DeviceType { get; set; } [MaxLength(100)] public string? Location { get; set; } public bool IsDeleted { get; set; } } }

4.3 RepairOrder.cs 报修工单实体

using DeviceRepair.Core.Enums; namespace DeviceRepair.Core.Entities { public class RepairOrder { public int Id { get; set; } public int UserId { get; set; } public int DeviceId { get; set; } public string ProblemDesc { get; set; } = string.Empty; public OrderStatus OrderStatus { get; set; } public int? RepairUserId { get; set; } public string? RepairRemark { get; set; } public DateTime CreateTime { get; set; } public DateTime? FinishTime { get; set; } public bool IsDeleted { get; set; } // 导航属性(EF Core联表使用) public User User { get; set; } = null!; public Device Device { get; set; } = null!; public User? RepairUser { get; set; } } }

4.4 SystemMessage.cs 消息实体(RabbitMQ 用)

namespace DeviceRepair.Core.Entities { public class SystemMessage { public int Id { get; set; } public int ReceiveUserId { get; set; } public string Content { get; set; } = string.Empty; public bool IsRead { get; set; } public DateTime CreateTime { get; set; } } }

5. Dtos 入参模型

新建Dtos/LoginDto.cs(登录入参)

namespace DeviceRepair.Core.Dtos { /// <summary> /// 登录请求参数 /// </summary> public class LoginDto { public string UserName { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; } }

Interfaces 接口层(仓储 + 服务接口)

6.1 通用基础仓储接口IBaseRepository.cs

所有仓储统一规范

using DeviceRepair.Core.Entities; namespace DeviceRepair.Core.Interfaces { /// <summary> /// 通用仓储接口 /// </summary> /// <typeparam name="T">实体</typeparam> public interface IBaseRepository<T> where T : class { Task<List<T>> GetListAsync(); Task<T?> GetByIdAsync(int id); Task AddAsync(T entity); Task UpdateAsync(T entity); Task DeleteAsync(int id); } }

6.2 用户仓储接口IUserRepository.cs

继承通用仓储,扩展自有方法

using DeviceRepair.Core.Entities; namespace DeviceRepair.Core.Interfaces { public interface IUserRepository : IBaseRepository<User> { /// <summary> /// 校验账号密码 /// </summary> Task<User?> CheckLoginAsync(string userName, string password); } }

6.3 账号服务接口IAccountService.cs

业务服务接口

using DeviceRepair.Core.Dtos; using DeviceRepair.Core; namespace DeviceRepair.Core.Interfaces { public interface IAccountService { /// <summary> /// 登录 /// </summary> Task<ResultModel<string>> LoginAsync(LoginDto dto); } }

Core 层全部完成,模型、枚举、DTO、接口全部定义完毕。


开发 DeviceRepair.Infrastructure(基础设施层)

职责:实现接口、EF 上下文、Dapper、JWT、服务注册扩展

1. 新建文件夹结构(Infrastructure)

DeviceRepair.Infrastructure ├─ Data # EF Core 数据库上下文 ├─ Repositories # 仓储实现(EF) ├─ Utils # 工具类:Jwt、Dapper、配置 └─ Extensions # 服务注册扩展(解耦 Program.cs)

2. Data 目录:数据库上下文AppDbContext.cs

using DeviceRepair.Core.Entities; using Microsoft.EntityFrameworkCore; namespace DeviceRepair.Infrastructure.Data { public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<User> Users => Set<User>(); public DbSet<Device> Devices => Set<Device>(); public DbSet<RepairOrder> RepairOrders => Set<RepairOrder>(); public DbSet<SystemMessage> SystemMessages => Set<SystemMessage>(); // 全局软删除过滤 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>().HasQueryFilter(u => !u.IsDeleted); modelBuilder.Entity<Device>().HasQueryFilter(d => !d.IsDeleted); modelBuilder.Entity<RepairOrder>().HasQueryFilter(o => !o.IsDeleted); modelBuilder.Entity<SystemMessage>().HasQueryFilter(m => true); } } }

3. Utils 工具类

3.1 ConfigHelper.cs 配置读取

using Microsoft.Extensions.Configuration; namespace DeviceRepair.Infrastructure.Utils { //.NET 官方推荐用依赖注入传 IConfiguration,而非静态全局变量。现在这种(静态帮助类),适合:个人练习、小型项目、快速开发 public static class ConfigHelper { //这是一个静态配置帮助类,专门用来读取项目配置文件里的数据库连接字符串,后续代码不用反复写读取逻辑,直接调用方法就能拿到连接串。 public static IConfiguration Configuration { get; set; } = null!; //IConfiguration:.NET 配置根对象,代表整个 appsettings.json 文件。 //固定语法:专门读取 appsettings.json 里 ConnectionStrings 节点下名为 SqlServer 的配置。 public static string GetConnectionString() { //任意地方调用拿连接串,string conn = ConfigHelper.GetConnectionString(); return Configuration.GetConnectionString("SqlServer") ?? string.Empty; } } }

3.2 JwtHelper.cs JWT 生成工具

using DeviceRepair.Core.Entities; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; namespace DeviceRepair.Infrastructure.Utils { //JWT 令牌生成工具类,登录成功后,用它生成登录凭证(Token),前端拿着这个令牌访问需要登录的接口,服务端就能识别用户身份。 public static class JwtHelper { public static string GenerateToken(User user, string secretKey, int expireMinutes) { //Claim:身份信息单元,就是把用户数据塞进令牌里,接口后续可以从令牌取出这些信息。 var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.UserName), new Claim("Role", user.Role.ToString()) }; //前端拿到 Token 后,后端不用再查数据库,直接解析就能拿到用户 ID、账号、角色。 // SymmetricSecurityKey:把传入的密钥字符串转成加密可用的字节格式 //SigningCredentials:指定加密算法(这里用 HmacSha256 对称加密) //作用:给令牌加签名,别人篡改令牌内容后,服务端能检测出来。 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); // 构建 JWT 令牌本体 // expires:令牌过期时间(当前时间 + 传入的分钟数) //claims:上面装好的用户身份信息 //signingCredentials:加密签名规则 var token = new JwtSecurityToken( expires: DateTime.Now.AddMinutes(expireMinutes), claims: claims, signingCredentials: cred); return new JwtSecurityTokenHandler().WriteToken(token); } } }

3.3 DapperHelper.cs Dapper 工具类(后续复杂查询用)

using Dapper; using Microsoft.Data.SqlClient; using System.Data; namespace DeviceRepair.Infrastructure.Utils { public static class DapperHelper { private static IDbConnection GetConn(string connStr) { return new SqlConnection(connStr); } public static async Task<List<T>> QueryAsync<T>(string connStr, string sql, object? param = null) { using var conn = GetConn(connStr); return (await conn.QueryAsync<T>(sql, param)).ToList(); } } }

4. Repositories 仓储实现

UserRepository.cs 实现 IUserRepository

using DeviceRepair.Core.Entities; using DeviceRepair.Core.Interfaces; using DeviceRepair.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace DeviceRepair.Infrastructure.Repositories { public class UserRepository : IUserRepository { private readonly AppDbContext _db; public UserRepository(AppDbContext db) { _db = db; } public async Task<List<User>> GetListAsync() { return await _db.Users.ToListAsync(); } public async Task<User?> GetByIdAsync(int id) { return await _db.Users.FindAsync(id); } public async Task AddAsync(User entity) { await _db.Users.AddAsync(entity); await _db.SaveChangesAsync(); } public async Task UpdateAsync(User entity) { _db.Users.Update(entity); await _db.SaveChangesAsync(); } public async Task DeleteAsync(int id) { var user = await GetByIdAsync(id); if (user != null) { user.IsDeleted = true; await UpdateAsync(user); } } // 登录校验 public async Task<User?> CheckLoginAsync(string userName, string password) { return await _db.Users .FirstOrDefaultAsync(u => u.UserName == userName && u.Password == password); } } }

5. Extensions 服务注册扩展(核心解耦)

新建ServiceCollectionExtensions.cs把所有依赖注入、JWT、数据库注册全部抽离,Program.cs保持极简。

using DeviceRepair.Core.Interfaces; using DeviceRepair.Infrastructure.Data; using DeviceRepair.Infrastructure.Repositories; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using System.Text; namespace DeviceRepair.Infrastructure.Extensions { public static class ServiceCollectionExtensions { /// <summary> /// 注册EF + 仓储 /// </summary> public static void AddDbAndRepositories(this IServiceCollection services, IConfiguration config) { string connStr = config.GetConnectionString("SqlServer")!; services.AddDbContext<AppDbContext>(opt => { opt.UseSqlServer(connStr); }); // 仓储注入 services.AddScoped<IUserRepository, UserRepository>(); } /// <summary> /// 注册JWT认证 /// </summary> public static void AddJwtAuthentication(this IServiceCollection services, IConfiguration config) { // 1. 从配置文件读取JWT加密密钥 string secretKey = config["Jwt:SecretKey"]!; // 2. 启用认证,默认使用JWT方案 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(opt => { // 配置Token校验规则 opt.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, // 不校验令牌签发方 ValidateAudience = false, // 不校验令牌接收方 ValidateLifetime = true, // 必开:校验令牌是否过期 // 验签密钥:必须和生成Token的密钥完全一致,防止篡改 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)) }; }); // 3. 启用授权功能(配合 [Authorize] 特性使用) services.AddAuthorization(); } } }

Infrastructure 层完成:EF、仓储、工具、服务扩展全部写完。


开发 DeviceRepair.Services(业务逻辑层)

业务模块拆分,只依赖接口,不碰数据库、不写 SQL。

1. 文件夹结构(Services)

DeviceRepair.Services └─ Modules └─ Account # 账号/登录模块 └─ AccountService.cs

2. 编写 AccountService.cs(实现 IAccountService)

using DeviceRepair.Core; using DeviceRepair.Core.Dtos; using DeviceRepair.Core.Entities; using DeviceRepair.Core.Interfaces; using DeviceRepair.Infrastructure.Utils; using Microsoft.Extensions.Configuration; namespace DeviceRepair.Services.Modules.Account { public class AccountService : IAccountService { private readonly IUserRepository _userRepo; private readonly IConfiguration _config; public AccountService(IUserRepository userRepo, IConfiguration config) { _userRepo = userRepo; _config = config; } public async Task<ResultModel<string>> LoginAsync(LoginDto dto) { // 1. 调用仓储查询用户 User? user = await _userRepo.CheckLoginAsync(dto.UserName, dto.Password); if (user == null) { return ResultModel<string>.Fail("账号或密码错误", 401); } // 2. 读取JWT配置、生成Token string secret = _config["Jwt:SecretKey"]!; int expire = int.Parse(_config["Jwt:ExpireMinutes"]!); string token = JwtHelper.GenerateToken(user, secret, expire); return ResultModel<string>.Success(token, "登录成功"); } } }

3. 在扩展类追加「业务服务注册」

回到DeviceRepair.Infrastructure/Extensions/ServiceCollectionExtensions.cs,新增方法:

/// <summary> /// 注册所有业务服务 /// </summary> public static void AddBusinessServices(this IServiceCollection services) { services.AddScoped<IAccountService, AccountService>(); }

Services 层完成,业务逻辑与数据访问彻底解耦。


第五阶段:开发 DeviceRepair.Api(启动项目 + 接口层)

职责:路由、控制器、过滤器、中间件、管道配置。

1. 文件夹结构(Api)

DeviceRepair.Api ├─ Controllers # 控制器 ├─ Filters # 自定义过滤器(后续添加) ├─ Middlewares # 自定义中间件(后续添加) ├─ appsettings.json └─ Program.cs

2. 配置 appsettings.json

{ "ConnectionStrings": { "SqlServer": "Server=.;Database=DeviceRepairDB;Trusted_Connection=True;TrustServerCertificate=True" }, "Jwt": { "SecretKey": "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdef", "ExpireMinutes": 60 }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }

说明:本地 SQL Express 把Server=.改为Server=.\SQLEXPRESS

3. 编写控制器 Controllers/AccountController.cs

RESTful + 版本路由 + 特性路由

using DeviceRepair.Core; using DeviceRepair.Core.Dtos; using DeviceRepair.Core.Interfaces; using Microsoft.AspNetCore.Mvc; namespace DeviceRepair.Api.Controllers { [Route("api/v1/[controller]")] [ApiController] public class AccountController : ControllerBase { private readonly IAccountService _accountService; public AccountController(IAccountService accountService) { _accountService = accountService; } /// <summary> /// 登录接口 POST /// </summary> [HttpPost("login")] public async Task<ActionResult<ResultModel<string>>> Login([FromBody] LoginDto dto) { var result = await _accountService.LoginAsync(dto); return Ok(result); } } }

4. 极简 Program.cs(使用扩展方法,一行注册)

using DeviceRepair.Infrastructure.Extensions; using DeviceRepair.Infrastructure.Utils; var builder = WebApplication.CreateBuilder(args); // 初始化配置工具 ConfigHelper.Configuration = builder.Configuration; // 1. 基础控制器 builder.Services.AddControllers(); // 2. 统一注册:数据库、仓储、业务服务、JWT builder.Services.AddDbAndRepositories(builder.Configuration); builder.Services.AddBusinessServices(); builder.Services.AddJwtAuthentication(builder.Configuration); // Swagger builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 开发环境开启Swagger if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } // 认证、授权(顺序不能乱) app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();

执行 EF Core 迁移命令

1. 打开【包管理器控制台】

  • 在 Visual Studio 顶部菜单:视图其他窗口包管理器控制台
  • 或者直接在下方搜索栏输入PMC打开。

2. 设置默认项目

在包管理器控制台的顶部,将默认项目设置为DeviceRepair.Infrastructure

3. 执行创建迁移命令

输入以下命令并回车:

Add-Migration InitialCreate
  • 这会在DeviceRepair.Infrastructure项目中创建一个Migrations文件夹,里面包含迁移代码。

4. 执行更新数据库命令

输入以下命令并回车:

Update-Database
  • EF Core 会自动根据你的实体和迁移文件,在SqlServer中创建DeviceRepairDB数据库和所有表。

5. SQL Server 执行建库建表脚本

打开 SSMS,执行下面 SQL,创建库、表、测试数据:

CREATE DATABASE DeviceRepairDB; GO USE DeviceRepairDB; GO -- 用户表 CREATE TABLE Users( Id INT PRIMARY KEY IDENTITY(1,1), UserName NVARCHAR(50) NOT NULL, Password NVARCHAR(50) NOT NULL, RealName NVARCHAR(50), Role INT NOT NULL DEFAULT 0, CreateTime DATETIME NOT NULL DEFAULT GETDATE(), IsDeleted BIT NOT NULL DEFAULT 0 ); -- 设备表 CREATE TABLE Devices( Id INT PRIMARY KEY IDENTITY(1,1), DeviceName NVARCHAR(100) NOT NULL, DeviceType NVARCHAR(50), Location NVARCHAR(100), IsDeleted BIT NOT NULL DEFAULT 0 ); -- 工单表 CREATE TABLE RepairOrders( Id INT PRIMARY KEY IDENTITY(1,1), UserId INT NOT NULL, DeviceId INT NOT NULL, ProblemDesc NVARCHAR(500) NOT NULL, OrderStatus INT NOT NULL DEFAULT 0, RepairUserId INT NULL, RepairRemark NVARCHAR(500), CreateTime DATETIME NOT NULL DEFAULT GETDATE(), FinishTime DATETIME NULL, IsDeleted BIT NOT NULL DEFAULT 0 ); -- 消息表 CREATE TABLE SystemMessages( Id INT PRIMARY KEY IDENTITY(1,1), ReceiveUserId INT NOT NULL, Content NVARCHAR(200) NOT NULL, IsRead BIT NOT NULL DEFAULT 0, CreateTime DATETIME NOT NULL DEFAULT GETDATE() ); -- 测试账号 INSERT INTO Users(UserName,Password,RealName,Role) VALUES ('staff','123456','普通员工',0), ('repair','123456','维修员',1), ('admin','123456','管理员',2); -- 测试设备 INSERT INTO Devices(DeviceName,DeviceType,Location) VALUES ('办公电脑A','电脑','1楼办公室'), ('打印机01','打印机','前台');

第六阶段:运行项目 & 验证整体流程

  1. DeviceRepair.Api设为启动项目

  2. 点击运行,打开 Swagger 页面

  3. 调用接口api/v1/Account/login入参:

    json

    { "UserName":"admin", "Password":"123456" }
  4. 正常返回200+Token整套架构跑通


下一阶段学习路线(按顺序继续)

当前已完成: ✅ 四层模块化架构搭建 ✅ 分层解耦 + 接口抽象 ✅ EF Core 基础使用 ✅ JWT 登录认证 ✅ RESTful + 版本路由

接下来按顺序逐个攻克剩余技术:

  1. 自定义过滤器(授权过滤、参数校验、操作日志)

  2. 自定义中间件(全局异常、跨域、请求日志)

  3. 新增设备 / 工单控制器,融合Dapper做复杂查询 / 分页

  4. 集成RabbitMQ模块化实现消息推送

  5. 对接 Vue3 前端

你现在确认项目能正常运行后,我们开始写过滤器

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 14:26:02

2026年阿里云Hermes Agent/OpenClaw配置Token Plan搭建保姆攻略

2026年阿里云Hermes Agent/OpenClaw配置Token Plan搭建保姆攻略。OpenClaw/Hermes Agen怎么部署配置Token Plan教程&#xff1a;OpenClaw是开源的个人AI助手&#xff0c;Hermes Agent则是一个能自我进化的AI智能体框架。阿里云提供计算巢、轻量服务器及无影云电脑三种部署OpenC…

作者头像 李华
网站建设 2026/6/13 14:24:56

生态规划实战:如何用景观连通性(Conefor)精准筛选你的MSPA生态源地?

生态规划实战&#xff1a;景观连通性分析与MSPA生态源地筛选的科学决策路径清晨的阳光透过窗帘缝隙洒在办公桌上&#xff0c;生态规划师李明正盯着电脑屏幕上一张布满绿色斑块的卫星地图发呆。这些看似随机的绿色区域&#xff0c;实际上承载着维持区域生态安全的重要功能。如何…

作者头像 李华
网站建设 2026/6/13 14:23:53

生态安全格局构建新思路:当MSPA遇见Conefor,如何用景观连通性筛选关键生态源地?

生态安全格局构建新思路&#xff1a;MSPA与Conefor联动的景观连通性分析方法生态安全格局构建已成为国土空间规划与生物多样性保护的核心工具。传统方法往往依赖主观经验设定面积阈值筛选生态源地&#xff0c;导致结果科学性不足。本文将介绍一种结合形态学空间格局分析&#x…

作者头像 李华
网站建设 2026/6/13 14:21:51

在互联网大厂求职:Java面试中的技术挑战与幽默互动

在互联网大厂求职&#xff1a;Java面试中的技术挑战与幽默互动 在当今竞争激烈的互联网行业&#xff0c;Java开发者的面试往往充满挑战与变化。本篇文章将模拟一场互联网大厂的Java面试&#xff0c;面试官严肃&#xff0c;候选人则是搞笑的水货程序员燕双非&#xff0c;让我们一…

作者头像 李华
网站建设 2026/6/13 14:21:50

大模型原生能力崛起:AI中间抽象层正在归零

1. 项目概述&#xff1a;这不是一次普通更新&#xff0c;而是一次架构级“蒸发”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题不是修辞&#xff0c;不是营销话术&#xff0c;更不是对某款新模型的夸张吹捧。它直指一个正在发生的、肉眼可见…

作者头像 李华