.NET 8 Web开发入门(二):C# 现代语法速成——为 Web API 量身定制

发布时间:2026/7/25 16:28:26

.NET 8 Web开发入门(二):C# 现代语法速成——为 Web API 量身定制 .NET 8 Web开发入门二C# 现代语法速成——为 Web API 量身定制在上一篇文章中我们搭建了第一个.NET 8 Web API项目并运行了默认的天气接口。但如果你对C#语法感到陌生写起代码来可能处处碰壁。别担心——这一篇我们将系统学习C#现代语法重点聚焦于Web API开发中最常用的特性。读完这篇文章你将能轻松看懂并编写.NET 8 Web API的核心代码。## 一、从基础开始变量与类型C#是强类型语言但现代C#7.0提供了很多语法糖让代码更简洁。在Web API中我们最常处理的是JSON数据因此了解值类型和引用类型至关重要。### 1.1 隐式类型变量varvar让编译器推断变量类型减少代码重复。在API控制器中我们经常用它接收查询结果。csharp// 示例1使用var简化变量声明var userId 42; // 编译器推断为intvar userName Alice; // 推断为stringvar isActive true; // 推断为bool// 在Web API中var常用于接收数据库查询结果var users await _context.Users.ToListAsync(); // 推断为ListUser### 1.2 可为空类型与空检查API请求中字段可能为null。C# 8引入了可空引用类型帮助我们在编译时避免NullReferenceException。csharp// 示例2处理可能为null的API输入public record UserRequest( string? NickName, // ?表示此字段可为null string Email);// 在控制器方法中使用空合并操作符[HttpPost]public IActionResult CreateUser(UserRequest request){ // 如果NickName为null则使用默认值新用户 var finalName request.NickName ?? 新用户; return Ok(new { Name finalName, Email request.Email });}### 1.3 记录类型RecordC# 9引入的record类型非常适合Web API的数据传输对象DTO。它自动提供值相等性、ToString()和Deconstruct方法。csharp// 使用record定义API响应模型public record ProductResponse( int Id, string Name, decimal Price, string? Description // 可为空字段);// 在控制器中返回record会自动序列化为JSON[HttpGet({id})]public ProductResponse GetProduct(int id){ // 实际项目会从数据库查询 return new ProductResponse(id, C#学习指南, 39.99m, 一本好书);}## 二、面向现代Web开发的核心语法### 2.1 异步编程async/awaitWeb API几乎都是异步的——等待数据库查询时释放线程提高服务器吞吐量。从C# 5开始async/await让异步代码写起来像同步代码。csharp// 使用async/await的控制器方法[HttpGet(users)]public async TaskActionResultListUserDto GetUsers(){ // 模拟异步数据库查询实际使用EF Core var users await _userService.GetAllAsync(); // 使用LINQ投影到DTO var result users.Select(u new UserDto( u.Id, u.Name, u.Email )).ToList(); return Ok(result);}### 2.2 LINQ与Lambda表达式LINQ语言集成查询让数据操作更声明式。Lambda表达式则是LINQ的核心构造块。在Web API中我们经常使用它们进行过滤、排序和投影。csharp// 使用LINQ和Lambda处理集合var products new ListProduct{ new Product(1, 鼠标, 99.99m), new Product(2, 键盘, 199.99m), new Product(3, 显示器, 1299.99m)};// 链式LINQ查询过滤价格100的商品按名称排序投影到DTOvar cheapProducts products .Where(p p.Price 100m) // Lambdap是当前元素 .OrderBy(p p.Name) // 按名称升序 .Select(p new ProductDto(p.Id, p.Name, p.Price)) .ToList();### 2.3 模式匹配Pattern MatchingC# 7的模式匹配让条件判断更灵活尤其适合处理API响应状态。csharp// 使用switch表达式进行模式匹配public string GetProductStatus(Product product) product switch{ { Price: 0 } 免费, { Price: 1000 } 高价商品, { Stock: 0 } 缺货, _ 正常 // 默认情况};// 在API中用于路由参数校验[HttpGet(search)]public IActionResult SearchProducts(string? category, decimal? maxPrice){ if (category is null maxPrice is null) return BadRequest(至少需要一个搜索条件); // 使用属性模式匹配 if (maxPrice is 10000m) return BadRequest(最高价格不能超过10000); return Ok(搜索参数有效);}## 三、高级语法让Web API更专业### 3.1 依赖注入与DI容器.NET 8内置了强大的依赖注入容器。我们通过接口和实现分离让代码更可测试、更解耦。csharp// 定义服务接口public interface IOrderService{ TaskOrderDto GetOrderAsync(int orderId);}// 实现服务public class OrderService : IOrderService{ private readonly ILoggerOrderService _logger; public OrderService(ILoggerOrderService logger) { _logger logger; } public async TaskOrderDto GetOrderAsync(int orderId) { _logger.LogInformation(查询订单 {OrderId}, orderId); // 实际从数据库查询 return new OrderDto(orderId, 待支付, DateTime.UtcNow); }}// 在Program.cs中注册服务// builder.Services.AddScopedIOrderService, OrderService();### 3.2 扩展方法与中间件扩展方法允许我们向现有类型添加新方法而不需修改原类型。这在构建自定义中间件时非常有用。csharp// 为字符串添加扩展方法public static class StringExtensions{ public static string ToSlug(this string input) { return input.ToLower().Replace( , -); }}// 在API中使用扩展方法[HttpPost(products)]public IActionResult CreateProduct([FromBody] CreateProductRequest request){ var slug request.Name.ToSlug(); // 调用扩展方法 return Created($/products/{slug}, request);}### 3.3 源生成器与最小API.NET 8的最小APIMinimal APIs利用C# 9的顶级语句和源生成器让我们用极少的代码创建API端点。csharp// Program.cs中的最小API示例var app builder.Build();// 使用lambda表达式定义端点app.MapGet(/hello/{name}, (string name) { return Results.Ok(new { Message $你好{name} });});// 支持依赖注入app.MapGet(/users/{id}, async (int id, IUserService service) { var user await service.GetUserAsync(id); return user is not null ? Results.Ok(user) : Results.NotFound();});app.Run();## 四、实战整合所有语法构建API现在让我们用学到的所有语法创建一个完整的用户管理API端点。csharp// 示例完整的用户注册API[ApiController][Route(api/[controller])]public class UsersController : ControllerBase{ private readonly IUserRepository _repo; private readonly ILoggerUsersController _logger; public UsersController(IUserRepository repo, ILoggerUsersController logger) { _repo repo; _logger logger; } [HttpPost(register)] public async TaskActionResultUserResponse Register([FromBody] RegisterRequest request) { // 使用模式匹配验证输入 if (request is { Email: null or , Password.Length: 6 }) return BadRequest(邮箱不能为空密码至少6位); // 异步调用仓储层 var existingUser await _repo.FindByEmailAsync(request.Email); if (existingUser is not null) return Conflict(该邮箱已被注册); // 创建用户使用record简化 var newUser new User { Name request.Name ?? 未命名用户, Email request.Email, CreatedAt DateTime.UtcNow }; await _repo.AddAsync(newUser); _logger.LogInformation(新用户注册{Email}, request.Email); // 返回201 Created响应 return CreatedAtAction( nameof(GetUser), new { id newUser.Id }, new UserResponse(newUser.Id, newUser.Name, newUser.Email) ); } [HttpGet({id})] public async TaskActionResultUserResponse GetUser(int id) { var user await _repo.GetByIdAsync(id); return user is not null ? Ok(new UserResponse(user.Id, user.Name, user.Email)) : NotFound(); }}// 请求/响应DTO使用recordpublic record RegisterRequest(string? Name, string Email, string Password);public record UserResponse(int Id, string Name, string Email);## 五、总结通过这篇教程我们从C#的基础变量类型出发逐步深入到异步编程、LINQ、模式匹配、依赖注入和最小API等现代语法。这些知识点不是孤立的——在.NET 8 Web API开发中它们相互配合让你能写出简洁、高效且可维护的后端服务。关键收获1.record类型是DTO的理想选择减少样板代码2.async/await让I/O操作不会阻塞线程3.LINQLambda是数据处理的核心武器4.模式匹配让条件逻辑更安全、更直观5.依赖注入让代码可测试、可扩展下一篇文章我们将深入Entity Framework Core学习如何用C#高效操作数据库。准备好了吗让我们继续向前

相关新闻