一、控制器设计:MVC架构的核心枢纽
在ASP.NET Core中,控制器是处理HTTP请求的"交通指挥中心"。它接收请求、协调业务逻辑,并返回响应。下面是一个典型的控制器示例,展示了RESTful风格的设计:
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IProductService _service;
// 依赖注入服务层
public ProductsController(IProductService service)
{
_service = service;
}
// GET: api/products
[HttpGet]
public async Task<IActionResult> GetAll()
{
var products = await _service.GetAllAsync();
return Ok(products); // 200状态码 + JSON数据
}
// GET: api/products/5
[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
var product = await _service.GetByIdAsync(id);
if (product == null) return NotFound(); // 404处理
return Ok(product);
}
}
关键设计原则:
- 保持控制器"瘦"——仅处理HTTP相关逻辑
- 使用
[ApiController]特性自动验证模型 - 通过
ActionResult<T>明确返回类型
二、中间件集成:请求处理流水线
中间件就像洋葱的层层包裹,每个组件都能处理请求和响应。我们来看一个自定义日志中间件的实现:
public class RequestLogMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public RequestLogMiddleware(
RequestDelegate next,
ILogger<RequestLogMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var stopwatch = Stopwatch.StartNew();
try
{
await _next(context); // 调用下一个中间件
}
finally
{
stopwatch.Stop();
_logger.LogInformation(
$"请求 {context.Request.Path} 耗时 {stopwatch.ElapsedMilliseconds}ms");
}
}
}
// 在Startup中注册
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<RequestLogMiddleware>();
// 其他中间件...
}
典型应用场景:
- 异常处理(
UseExceptionHandler) - 静态文件服务(
UseStaticFiles) - 身份验证(
UseAuthentication)
三、EF Core数据访问:优雅的数据库交互
Entity Framework Core提供了强大的LINQ查询能力。以下是带有事务管理的仓储模式示例:
public class ProductRepository : IProductRepository
{
private readonly AppDbContext _context;
public ProductRepository(AppDbContext context)
{
_context = context;
}
public async Task AddWithTransactionAsync(Product product)
{
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
await _context.Products.AddAsync(product);
await _context.SaveChangesAsync();
// 模拟关联操作
await _context.ProductLogs.AddAsync(
new ProductLog { ProductId = product.Id, Action = "Create" });
await _context.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
// 复杂查询示例
public async Task<List<Product>> GetExpensiveProductsAsync(decimal minPrice)
{
return await _context.Products
.Where(p => p.Price > minPrice)
.Include(p => p.Category) // 加载关联数据
.OrderByDescending(p => p.Price)
.AsNoTracking() // 只读场景优化
.ToListAsync();
}
}
性能优化技巧:
- 使用
AsNoTracking减少内存开销 - 通过
Include/ThenInclude控制关联加载 - 批量操作考虑
ExecuteUpdate/ExecuteDelete(EF Core 7+)
四、综合应用场景与技术选型
电商系统案例:
// 组合中间件、控制器和EF Core的完整流程
[Authorize]
[ApiController]
public class OrderController : ControllerBase
{
private readonly IOrderService _service;
[HttpPost("checkout")]
public async Task<IActionResult> Checkout([FromBody] CheckoutDto dto)
{
// 模型验证自动执行(得益于[ApiController])
var result = await _service.ProcessOrderAsync(
User.GetUserId(), // 从认证中间件获取用户ID
dto.Items);
return result.Success ?
Ok(new { OrderId = result.OrderId }) :
BadRequest(result.Error);
}
}
技术对比:
| 方案 | 优点 | 缺点 |
|---------------|--------------------------|-----------------------|
| 原生ADO.NET | 极致性能 | 开发效率低 |
| Dapper | 轻量级,适合简单查询 | 复杂映射需要手工处理 |
| EF Core | 开发体验好,功能全面 | 学习曲线较陡 |
五、注意事项与最佳实践
并发控制:
[HttpPut("{id}")] public async Task<IActionResult> UpdateProduct( int id, [FromBody] ProductUpdateDto dto) { var product = await _context.Products .FirstOrDefaultAsync(p => p.Id == id); if (product == null) return NotFound(); // 乐观并发检查 if (product.Version != dto.Version) return Conflict("数据已被修改"); // 更新操作... }安全建议:
- 始终使用参数化查询防止SQL注入
- 生产环境禁用开发人员异常页面
- 实施适当的CORS策略
性能陷阱:
- N+1查询问题(可通过
Include或显式加载避免) - 大对象序列化(考虑使用
[JsonIgnore]或DTO投影)
- N+1查询问题(可通过
六、总结与展望
现代ASP.NET Core开发已经形成了清晰的模式:精简的控制器作为入口,可插拔的中间件处理横切关注点,EF Core提供高效的数据库访问。随着.NET 8的发布,诸如原生AOT编译、改进的Minimal API等特性将进一步丰富技术选型。建议在实际项目中根据团队熟悉度和业务复杂度,在开发效率与运行时性能之间找到平衡点。
评论