10.1 Web 应用架构与 HTTP 协议
核心概念:ASP.NET Core 采用 “请求 – 响应” 模型,基于 HTTP/HTTPS 协议通信。HTTP 协议核心要素包括:请求方法(GET/POST/PUT/DELETE)、状态码(200 成功 / 404 未找到 / 500 服务器错误)、请求头(
Authorization/Content-Type)、响应头(Cache-Control)。
架构分层:表现层(API 控制器 / 页面)→业务逻辑层(服务)→数据访问层(EF Core),通过依赖注入解耦各层。
10.2ASP.NETCore 项目结构解析
典型项目结构(.NET 8 Web API):
MyWebApi/
├─ Controllers/ # 控制器(处理HTTP请求)
├─ Services/ # 业务逻辑服务
├─ Models/ # 数据模型(请求/响应/实体)
├─ Data/ # 数据访问(DbContext)
├─ appsettings.json # 配置文件(连接字符串/日志)
├─ Program.cs # 入口文件(服务注册/中间件管道)
└─ MyWebApi.csproj # 项目依赖配置
Program.cs 核心作用:注册服务(如 EF Core、认证)、构建中间件管道(处理请求流程)。
10.3 中间件管道与请求处理
中间件原理:请求依次经过多个中间件(如日志→认证→路由→控制器),每个中间件可修改请求 / 响应,或终止管道(如 401 未授权)。
自定义中间件案例:请求日志中间件(记录所有请求的路径、方法、耗时):
// 1. 定义中间件类
public class RequestLoggerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggerMiddleware> _logger;
// 构造函数注入下一个中间件和日志器
public RequestLoggerMiddleware(RequestDelegate next, ILogger<RequestLoggerMiddleware> logger)
{
_next = next;
_logger = logger;
}
// 中间件核心方法(InvokeAsync)
public async Task InvokeAsync(HttpContext context)
{
// 1. 处理请求前:记录开始时间和请求信息
var startTime = DateTime.Now;
var requestPath = context.Request.Path;
var httpMethod = context.Request.Method;
_logger.LogInformation($"请求开始:{httpMethod} {requestPath}");
// 2. 调用下一个中间件(继续管道)
await _next(context);
// 3. 处理响应后:记录耗时和响应状态码
var duration = DateTime.Now - startTime;
var statusCode = context.Response.StatusCode;
_logger.LogInformation($"请求结束:{statusCode},耗时:{duration.TotalMilliseconds}ms");
}
}
// 2. 扩展方法:简化中间件注册
public static class RequestLoggerMiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogger(this IApplicationBuilder app)
{
return app.UseMiddleware<RequestLoggerMiddleware>();
}
}
// 3. 在Program.cs注册中间件(需在路由之前)
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRequestLogger(); // 注册自定义日志中间件
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
10.4 依赖注入与服务生命周期
依赖注入(DI)核心:ASP.NET Core 内置 DI 容器,管理服务的创建与销毁,避免硬编码依赖,便于测试和维护。
服务生命周期(3 种核心类型):
|
生命周期 |
特点 |
适用场景 |
|
Transient |
每次请求创建新实例 |
轻量级、无状态服务(如工具类) |
|
Scoped |
每个 HTTP 请求内复用一个实例 |
数据访问服务(如 DbContext) |
|
Singleton |
应用启动后创建一个实例,全局复用 |
全局配置、缓存服务 |
实战案例:注册与使用业务服务:
// 1. 定义业务接口与实现
public interface IUserService
{
Task<string> GetUserNameByIdAsync(int id);
}
public class UserService : IUserService
{
private readonly AppDbContext _dbContext;
// 注入DbContext(Scoped生命周期)
public UserService(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<string> GetUserNameByIdAsync(int id)
{
var user = await _dbContext.Users.FindAsync(id);
return user?.Name ?? "未知用户";
}
}
// 2. 在Program.cs注册服务(Scoped生命周期)
builder.Services.AddScoped<IUserService, UserService>();
// 注册DbContext(默认Scoped)
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// 3. 在控制器中注入使用
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
// 构造函数注入IUserService
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetUserName(int id)
{
var name = await _userService.GetUserNameByIdAsync(id);
return Ok(new { UserId = id, UserName = name });
}
}
10.5 配置系统与环境管理
配置来源优先级(从高到低):命令行参数 → 环境变量 → appsettings.{Environment}.json → appsettings.json → 内置配置。
实战案例:多环境配置与读取:
创建环境配置文件:
- appsettings.Development.json(开发环境):
{
"Logging": { "LogLevel": { "Default": "Debug" } },
"AppSettings": { "ApiBaseUrl": "https://dev.api.com", "MaxRetryCount": 2 }
}
- appsettings.Production.json(生产环境):
{
"Logging": { "LogLevel": { "Default": "Warning" } },
"AppSettings": { "ApiBaseUrl": "https://prod.api.com", "MaxRetryCount": 5 }
}
- 绑定配置到实体类:
// 定义配置实体
public class AppSettings
{
public string ApiBaseUrl { get; set; }
public int MaxRetryCount { get; set; }
}
// 在Program.cs绑定配置
builder.Services.Configure<AppSettings>(
builder.Configuration.GetSection("AppSettings"));
- 使用配置(控制器或服务中):
public class ConfigController : ControllerBase
{
private readonly IOptions<AppSettings> _appSettings;
// 注入IOptions<AppSettings>
public ConfigController(IOptions<AppSettings> appSettings)
{
_appSettings = appSettings;
}
[HttpGet("settings")]
public IActionResult GetSettings()
{
var settings = _appSettings.Value;
return Ok(new
{
CurrentEnv = builder.Environment.EnvironmentName,
// 获取当前环境(Development/Production)
ApiUrl = settings.ApiBaseUrl,
MaxRetry = settings.MaxRetryCount
});
}
}
- 切换环境:运行时通过命令行指定环境:dotnet run –environment Production。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...





