第 10 章 ASP.NET Core 基础

内容分享12小时前发布
0 0 0

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。
© 版权声明

相关文章

暂无评论

none
暂无评论...