Document

.NET Core Web API 从0到1:30个核心知识点与完整Demo,打造生产级API(一)

连接访问:https://mp.weixin.qq.com/s/bM38yO8l6fv41nrL_QXblA

 

.NET Core Web API 实战指南(一)

01

前言

随着云计算、微服务架构和前后端分离开发模式的普及,Web API 成为了现代软件开发的核心组件。作为连接前端应用(如 Web、移动端)与后端服务的关键桥梁,Web API 不仅承载着数据交互的职责,还承担着业务逻辑处理、身份认证、权限控制、日志记录、性能优化等多重任务。

在众多后端开发技术栈中,.NET Core(现称为 .NET 5+)因其高性能、跨平台、模块化设计和强大的生态系统,成为构建现代 Web API 的理想选择。它不仅支持 Windows、Linux 和 macOS,还能轻松部署在 Docker 容器或云原生环境中,非常适合微服务架构和 DevOps 实践。

本文将深入探讨 .NET Core Web API 的基础实践与应用,从项目结构、核心概念、设计模式、安全机制到实际部署进行全面解析,并结合大量可运行的代码示例,帮助开发者掌握从零开始构建一个生产级 Web API 的完整流程。

说明:最近有人留言,写一个简单Demo,虽然本文入门级Net Core Web API项目,以下内容将以高度结构化、详尽的方式呈现核心知识点与完整代码示例。读者可将其作为系统学习 .NET Core Web API 的权威指南,后续可根据需要扩展每个章节。

02

第一章:.NET Core Web API 概述

1.1 什么是 Web API?

Web API(Application Programming Interface)是指基于 HTTP 协议暴露的服务接口,通常用于不同系统之间的数据交换。在 RESTful 架构风格下,Web API 使用标准的 HTTP 方法(GET、POST、PUT、DELETE)对资源进行操作。

例如:

  • GET /api/users 获取用户列表
  • POST /api/users 创建新用户
  • PUT /api/users/1 更新 ID 为 1 的用户
  • DELETE /api/users/1 删除用户

03

1.2 为什么选择 .NET Core 构建 Web API?

特性说明
高性能 .NET Core 是目前性能最强的后端框架之一,在 TechEmpower 基准测试中长期名列前茅。
跨平台 支持 Windows、Linux、macOS,可在任意操作系统上运行。
依赖注入(DI)原生支持 内置 IoC 容器,便于实现松耦合设计。
配置系统灵活 支持 JSON、环境变量、命令行等多种配置源。
中间件管道机制 强大的请求处理管道,易于扩展功能(如日志、认证、CORS)。
工具链完善 Visual Studio、VS Code、CLI 工具链成熟,开发效率高。
云原生友好 天然支持 Docker、Kubernetes、Azure、AWS 等云平台。

 

04

1.3 .NET Core 与 ASP.NET Core 的关系

  • .NET Core 是运行时和基础类库(BCL),提供通用编程能力。
  • ASP.NET Core 是构建 Web 应用的框架,运行在 .NET Core 之上。
  • 因此,“.NET Core Web API” 实际上指的是使用 ASP.NET Core 框架创建的 Web API。

从 .NET 5 开始,微软统一了命名,统称为 .NET,不再区分 .NET Framework、.NET Core、.NET Standard。但开发 Web API 仍使用 ASP.NET Core 框架。


第二章:环境搭建与项目初始化

2.1 开发环境准备

  1. 安装 .NET SDK

    • 下载地址:https://dotnet.microsoft.com/download
    • 推荐版本:.NET 8(LTS)或 .NET 9(预览)
    • 验证安装:
dotnet --version# 输出示例:8.0.100
  1. IDE 推荐

    • Visual Studio 2022(Windows)
    • Visual Studio Code(跨平台)
    • Rider(JetBrains)
  2. 数据库(可选)

    • SQL Server / PostgreSQL / MySQL / SQLite

06

2.2 创建第一个 Web API 项目

使用 .NET CLI 创建项目:

# 创建项目目录mkdir MyFirstApicd MyFirstApi# 创建 Web API 项目dotnet new webapi -n MyFirstApicd MyFirstApi

项目结构说明:

MyFirstApi/├── Controllers/          # 控制器存放目录│   └── WeatherForecastController.cs├── Program.cs            # 主入口文件(.NET 6+ 合并了 Startup.cs)├── appsettings.json      # 配置文件├── appsettings.Development.json└── MyFirstApi.csproj     # 项目文件

07

2.3 运行项目

dotnet run

默认启动 Kestrel 服务器,监听 https://localhost:5001 和 http://localhost:5000

访问 https://localhost:5001/weatherforecast 可看到 JSON 格式的天气预报数据

08

第三章:核心概念解析

3.1 Program.cs:应用启动与配置

在 .NET 6+ 中,Program.cs 合并了 Startup.cs 的功能,采用 Minimal APIs 或传统 MVC 模式。

Minimal APIs 示例

var builder = WebApplication.CreateBuilder(args);// 添加服务到容器builder.Services.AddControllers();builder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();var app = builder.Build();// 配置 HTTP 请求管道if (app.Environment.IsDevelopment()){    app.UseSwagger();    app.UseSwaggerUI();}app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.Run();

关键方法解释

方法作用
CreateBuilder(args) 创建 WebApplicationBuilder,用于配置服务和中间件
AddControllers() 添加 MVC 控制器服务
AddSwaggerGen() 添加 Swagger 文档生成服务
UseSwagger() 启用 Swagger 中间件
UseHttpsRedirection() 将 HTTP 请求重定向到 HTTPS
UseAuthorization() 启用授权中间件
MapControllers() 映射控制器路由

 

09

第四章:控制器与路由设计

4.1 控制器(Controller)基础

控制器是处理 HTTP 请求的核心组件,继承自 ControllerBase(无视图支持)或 Controller(支持视图)。

示例:用户控制器

[ApiController][Route("api/[controller]")]public class UsersController : ControllerBase{    private static readonly List<User> _users = new();    // GET: api/users    [HttpGet]    public ActionResult<IEnumerable<User>> Get()    {        return Ok(_users);    }    // GET: api/users/5    [HttpGet("{id}")]    public ActionResult<User> Get(int id)    {        var user = _users.FirstOrDefault(u => u.Id == id);        if (user == null)            return NotFound();        return Ok(user);    }    // POST: api/users    [HttpPost]    public ActionResult<User> Post([FromBody] CreateUserRequest request)    {        var user = new User        {            Id = _users.Count + 1,            Name = request.Name,            Email = request.Email        };        _users.Add(user);        return CreatedAtAction(nameof(Get), new { id = user.Id }, user);    }    // PUT: api/users/5    [HttpPut("{id}")]    public IActionResult Put(int id, [FromBody] UpdateUserRequest request)    {        var user = _users.FirstOrDefault(u => u.Id == id);        if (user == null)            return NotFound();        user.Name = request.Name;        user.Email = request.Email;        return NoContent();    }    // DELETE: api/users/5    [HttpDelete("{id}")]    public IActionResult Delete(int id)    {        var user = _users.FirstOrDefault(u => u.Id == id);        if (user == null)            return NotFound();        _users.Remove(user);        return NoContent();    }}

10

4.2 路由(Routing)机制

ASP.NET Core 支持两种路由方式:

  1. 传统路由(Convention-based)

app.UseEndpoints(endpoints =>{    endpoints.MapControllerRoute(        name: "default",        pattern: "api/{controller}/{action}/{id?}");});
  1. 属性路由(Attribute-based)(推荐)

    • 使用 [Route][HttpGet] 等特性定义路由
    • 更精确、更灵活

路由模板语法

模板匹配示例
api/users 固定路径
api/users/{id} 路径参数
api/users/{id:int} 类型约束(int)
api/users/{name?} 可选参数
api/users/{*path} 通配符

 

11

第五章:模型与数据验证

5.1 数据传输对象(DTO)设计

避免直接暴露实体类,使用 DTO 进行数据传输。

// 请求 DTOpublic class CreateUserRequest{    [Required(ErrorMessage = "姓名不能为空")]    [StringLength(50, MinimumLength = 2, ErrorMessage = "姓名长度必须在2-50之间")]    public string Name { get; set; }    [Required(ErrorMessage = "邮箱不能为空")]    [EmailAddress(ErrorMessage = "邮箱格式不正确")]    public string Email { get; set; }}// 响应 DTOpublic class UserResponse{    public int Id { get; set; }    public string Name { get; set; }    public string Email { get; set; }    public DateTime CreatedAt { get; set; }}

12

5.2 模型验证

ASP.NET Core 自动验证 [ApiController] 标记的控制器中的模型。

[ApiController][Route("api/[controller]")]public class UsersController : ControllerBase{    [HttpPost]    public IActionResult Create([FromBody] CreateUserRequest request)    {        if (!ModelState.IsValid)        {            return BadRequest(ModelState);        }        // 处理逻辑        return CreatedAtAction(nameof(Get), new { id = 1 }, request);    }}

自定义验证属性

public class ValidEmailDomainAttribute : ValidationAttribute{    private readonly string _allowedDomain;    public ValidEmailDomainAttribute(string allowedDomain)    {        _allowedDomain = allowedDomain;    }    protected override ValidationResult IsValid(object value, ValidationContext validationContext)    {        if (value is string email)        {            if (email.EndsWith($"@{_allowedDomain}"))                return ValidationResult.Success;            return new ValidationResult($"邮箱必须使用 {@_allowedDomain} 域名。");        }        return ValidationResult.Success;    }}// 使用[ValidEmailDomain("example.com")]public string Email { get; set; }

13

第六章:依赖注入(DI)与服务注册

6.1 依赖注入原理

DI 是一种设计模式,通过构造函数注入依赖项,实现松耦合。

public interface IUserService{    Task<IEnumerable<User>> GetAllAsync();    Task<User> GetByIdAsync(int id);    Task<User> CreateAsync(CreateUserRequest request);}public class UserService : IUserService{    public async Task<IEnumerable<User>> GetAllAsync() => await Task.FromResult(_users);    // 其他实现...}// 控制器中使用[ApiController][Route("api/[controller]")]public class UsersController : ControllerBase{    private readonly IUserService _userService;    public UsersController(IUserService userService)    {        _userService = userService;    }    [HttpGet]    public async Task<ActionResult<IEnumerable<User>>> Get()    {        var users = await _userService.GetAllAsync();        return Ok(users);    }}

14

6.2 服务生命周期

生命周期说明
AddTransient<T> 每次请求都创建新实例
AddScoped<T> 每个请求创建一个实例(推荐用于数据库上下文)
AddSingleton<T> 应用生命周期内共享一个实例

 

builder.Services.AddTransient<IEmailService, EmailService>();builder.Services.AddScoped<IUserService, UserService>();builder.Services.AddSingleton<ICacheService, RedisCacheService>();

15

第七章:Entity Framework Core 数据访问

7.1 安装 EF Core

dotnet add package Microsoft.EntityFrameworkCore.SqlServerdotnet add package Microsoft.EntityFrameworkCore.Tools

16

7.2 实体与 DbContext

public class User{    public int Id { get; set; }    public string Name { get; set; }    public string Email { get; set; }    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;}

public class AppDbContext : DbContext{   
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
 
public DbSet<User> Users { get; set; }
}

17

7.3 配置 DbContext

// Program.csbuilder.Services.AddDbContext<AppDbContext>(options =>    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// appsettings.json"ConnectionStrings"{  "DefaultConnection""Server=localhost;Database=MyApiDb;User Id=sa;Password=YourStrong@Pass123;TrustServerCertificate=true;"}

18

7.4 使用 Repository 模式

public interface IUserRepository{    Task<IEnumerable<User>> GetAllAsync();    Task<User> GetByIdAsync(int id);    Task<User> AddAsync(User user);    Task<boolDeleteAsync(int id);}public class UserRepository : IUserRepository{    private readonly AppDbContext _context;    public UserRepository(AppDbContext context) => _context = context;    public async Task<IEnumerable<User>> GetAllAsync() => await _context.Users.ToListAsync();    public async Task<User> GetByIdAsync(int id) => await _context.Users.FindAsync(id);    public async Task<User> AddAsync(User user)    {        _context.Users.Add(user);        await _context.SaveChangesAsync();        return user;    }    public async Task<boolDeleteAsync(int id)    {        var user = await _context.Users.FindAsync(id);        if (user == null) return false;        _context.Users.Remove(user);        await _context.SaveChangesAsync();        return true;    }}

注册服务:

builder.Services.AddScoped<IUserRepository, UserRepository>();

19

第八章:异常处理与日志记录

8.1 全局异常处理中间件

// 自定义异常处理中间件public class ExceptionHandlingMiddleware{    private readonly RequestDelegate _next;    private readonly ILogger<ExceptionHandlingMiddleware> _logger;    public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)    {        _next = next;        _logger = logger;    }    public async Task InvokeAsync(HttpContext context)    {        try        {            await _next(context);        }        catch (Exception ex)        {            _logger.LogError(ex, "发生未处理异常:{Message}", ex.Message);            await HandleExceptionAsync(context, ex);        }    }    private static async Task HandleExceptionAsync(HttpContext context, Exception exception)    {        context.Response.ContentType = "application/json";        context.Response.StatusCode = exception switch        {            NotFoundException => StatusCodes.Status404NotFound,            ValidationException => StatusCodes.Status400BadRequest,            _ => StatusCodes.Status500InternalServerError        };        var response = new        {            StatusCode = context.Response.StatusCode,            Message = "发生错误,请联系管理员。",            // Production 环境下不返回详细信息            Detailed = context.RequestServices.GetRequiredService<IWebHostEnvironment>().IsDevelopment() ? exception.Message : null        };        await context.Response.WriteAsJsonAsync(response);    }}// 注册中间件app.UseMiddleware<ExceptionHandlingMiddleware>();

20

8.2 日志记录

public class UserService{    private readonly ILogger<UserService> _logger;    public UserService(ILogger<UserService> logger) => _logger = logger;    public async Task<User> CreateAsync(CreateUserRequest request)    {        _logger.LogInformation("创建用户:{Name}", request.Name);        // 业务逻辑        _logger.LogInformation("用户创建成功,ID: {UserId}", user.Id);        return user;    }}

配置日志(appsettings.json):

"Logging"{  "LogLevel"{    "Default""Information",    "Microsoft.AspNetCore""Warning"  }}

21

第九章:安全性:身份认证与授权

9.1 JWT 身份认证

安装包

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

生成 JWT Token

public interface ITokenService{    string GenerateToken(User user);}public class TokenService : ITokenService{    private readonly IConfiguration _config;    public TokenService(IConfiguration config) => _config = config;    public string GenerateToken(User user)    {        var claims = new[]        {            new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),            new Claim(JwtRegisteredClaimNames.Email, user.Email),            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())        };        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);        var token = new JwtSecurityToken(            issuer: _config["Jwt:Issuer"],            audience: _config["Jwt:Audience"],            claims: claims,            expires: DateTime.Now.AddMinutes(30),            signingCredentials: creds);        return new JwtSecurityTokenHandler().WriteToken(token);    }}

配置认证服务

// Program.csbuilder.Services.AddAuthentication(options =>{    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(options =>{    options.TokenValidationParameters = new TokenValidationParameters    {        ValidateIssuer = true,        ValidateAudience = true,        ValidateLifetime = true,        ValidateIssuerSigningKey = true,        ValidIssuer = builder.Configuration["Jwt:Issuer"],        ValidAudience = builder.Configuration["Jwt:Audience"],        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))    };});app.UseAuthentication();app.UseAuthorization();

登录接口

[HttpPost("login")]public IActionResult Login([FromBody] LoginRequest request){    // 验证用户名密码(此处简化)    var user = _userService.ValidateUser(request.Username, request.Password);    if (user == null)        return Unauthorized();    var token = _tokenService.GenerateToken(user);    return Ok(new { Token = token });}

授权访问

[Authorize][HttpGet("profile")]public IActionResult GetProfile(){    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);    var user = _userService.GetByIdAsync(int.Parse(userId));    return Ok(user);}

22

第十章:API 文档:Swagger / OpenAPI

10.1 集成 Swagger

dotnet add package Swashbuckle.AspNetCore
// Program.csbuilder.Services.AddSwaggerGen(c =>{    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });    // 添加 JWT 认证支持    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme    {        In = ParameterLocation.Header,        Description = "请输入 JWT Token",        Name = "Authorization",        Type = SecuritySchemeType.Http,        BearerFormat = "JWT",        Scheme = "bearer"    });    c.AddSecurityRequirement(new OpenApiSecurityRequirement    {        {            new OpenApiSecurityScheme            {                Reference = new OpenApiReference                {                    Type = ReferenceType.SecurityScheme,                    Id = "Bearer"                }            },            Array.Empty<string>()        }    });});// 启用中间件if (app.Environment.IsDevelopment()){    app.UseSwagger();    app.UseSwaggerUI();}

访问 https://localhost:5001/swagger 查看交互式 API 文档。

23

第十一章:性能优化与缓存

11.1 响应缓存

// 启用响应缓存服务builder.Services.AddResponseCaching();app.UseResponseCaching();// 在控制器上启用缓存[HttpGet][ResponseCache(Duration 60, VaryByQueryKeys = new[] { "id" })]public async Task<ActionResult<IEnumerable<User>>> Get(){    var users await _userService.GetAllAsync();    return Ok(users);}

24

11.2 使用 Redis 缓存

dotnet add package StackExchange.Redis
public class RedisCacheService : ICacheService{    private readonly IDatabase _database;  
  public RedisCacheService(IConnectionMultiplexer redis)
    {        _database = redis.GetDatabase();    }   
 public async Task<TGetAsync<T>(string key)
    {        var value = await _database.StringGetAsync(key);       
 return value.IsNullOrEmpty ? default : JsonSerializer.Deserialize<T>(value);
    }    

public async Task SetAsync<T>(string key, T value, TimeSpan? expiry = null)
 
  {
        var json = JsonSerializer.Serialize(value);       
 await _database.StringSetAsync(key, json, expiry);
    }}

25

第十二章:部署与 DevOps

12.1 发布到 IIS

dotnet publish -c Release -o ./publish

配置 web.config,安装 ASP.NET Core Hosting Bundle。

26

12.2 Docker 部署

# DockerfileFROM mcr.microsoft.com/dotnet/aspnet:8.0 AS baseWORKDIR /appEXPOSE 80FROM mcr.microsoft.com/dotnet/sdk:8.0 AS buildWORKDIR /srcCOPY . .RUN dotnet restoreRUN dotnet publish -c Release -o /app/publishFROM base AS finalWORKDIR /appCOPY --from=build /app/publish .ENTRYPOINT ["dotnet", "MyFirstApi.dll"]

构建并运行:

docker build -t myapi .docker run -d -p 8080:80 myapi

27

第十三章:最佳实践总结

  1. 使用 DTO 而非实体类直接传输
  2. 合理使用依赖注入
  3. 统一异常处理
  4. 启用 HTTPS
  5. 使用 Swagger 文档 API
  6. 实现身份认证与授权
  7. 日志记录关键操作
  8. 单元测试与集成测试
  9. 性能监控与调优
  10. CI/CD 自动化部署

28

结语

.NET Core Web API 凭借其高性能、现代化的设计理念和强大的生态系统,已成为企业级后端开发的首选技术之一。通过本文的系统讲解与代码实践,相信你已掌握了从零构建一个完整 Web API 的核心技能。

29

如果后期时间充足,会把下面的知识和样例做了:

  • 微服务架构(gRPC、Ocelot 网关、Nacos)
  • 事件驱动架构(RabbitMQ、Kafka)
  • 分布式事务(Saga 模式)
  • 领域驱动设计(DDD)
  • Kubernetes 部署

技术 · 目录
上一篇.NET Core 实战:深入理解与应用领域驱动设计 (DDD)下一篇EF Core 性能优化终极指南:47 个高手都在用的避坑技巧
 
 
 
 
posted @ 2025-09-16 09:41  从未被超越  阅读(863)  评论(0)    收藏  举报