C# WebAPI 开发核心实践与架构设计
RESTful API 架构设计原则
构建可扩展、易维护的Web服务需遵循一致的架构规范。基于资源的统一接口是核心,每个实体通过唯一标识符(URI)定位,操作通过标准HTTP动词(GET、POST、PUT、DELETE)完成。系统应保持无状态,服务器不保存客户端上下文,所有请求信息必须包含在请求中。同时,推荐采用超媒体驱动的导航机制(HATEOAS),使客户端能根据响应中的链接动态发现可用操作。
开发环境搭建与项目初始化
使用Visual Studio创建ASP.NET Core WebAPI项目时,选择"API"模板可快速生成基础结构。配置项目时,确保启用".NET Web开发"工作负载,并安装最新版.NET SDK。通过命令行验证:`dotnet --version` 确认运行时环境就绪。
数据库集成与数据访问层实现
利用Entity Framework Core作为数据持久化层,首先注册DbContext服务:
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Default")));
定义上下文类并映射实体关系,例如:
public class AppDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Order> Orders { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<User>()
.HasMany(u => u.Orders)
.WithOne(o => o.User)
.HasForeignKey(o => o.UserId);
}
}
模型与数据契约设计
区分不同用途的数据载体:轻量级数据传输对象(DTO)用于跨层通信,视图模型(ViewModel)则用于前端展示逻辑。示例:
public class UserDto
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
}
public class UserViewModel
{
public string DisplayName { get; set; }
public string AvatarUrl { get; set; }
public DateTime CreatedAt { get; set; }
}
控制器逻辑与请求处理
控制器负责接收请求、执行业务逻辑并返回结果。动作方法使用特性标记路由和请求类型:
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet("{id:int}")]
public IActionResult GetById(int id)
{
var user = _userService.FindById(id);
return user != null ? Ok(user) : NotFound();
}
[HttpPost]
public IActionResult Create([FromBody] CreateUserDto dto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
_userService.Create(dto);
return CreatedAtAction(nameof(GetById), new { id = dto.Id }, dto);
}
}
路由策略与版本管理
通过路由模板实现路径规范化,支持参数约束与默认值:
[HttpGet("{action=GetAll}")]
public IActionResult GetAll() => Ok(_users);
为支持多版本接口,可在路由中嵌入版本号:
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class UsersController : ControllerBase { ... }
异常处理与日志记录
在控制器中捕获异常并记录关键错误信息:
try
{
var result = await _service.ProcessAsync(request);
return Ok(result);
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "Business rule violation: {Message}", ex.Message);
return StatusCode(422, new { error = "Invalid operation" });
}
可通过中间件全局捕获未处理异常,提升系统健壮性。