新手向:如何在.NET中实现含嵌套对象的HttpPost API?
.NET新手教程:实现嵌套对象的HttpPost API并存库
咱一步步来,从补全模型到写API,再到存库测试,全给你捋清楚。
1. 补全完整领域模型
你已经有了DestinationPlan,现在把剩下的三个实体补上。每个实体得加主键(EF Core认这个才能正常生成数据表),还要加关联外键,让EF Core知道它们之间的嵌套关系:
namespace Itinerary.API.Models.Domain { public class DestinationPlan { [Key] public Guid Id { get; set; } = Guid.NewGuid(); // 自动生成唯一主键 public List<DestinationPlanDay> DestinationPlanDays { get; set; } = new(); // 初始化集合避免空引用报错 } public class DestinationPlanDay { [Key] public Guid Id { get; set; } = Guid.NewGuid(); public DateTime Date { get; set; } public int DayNumber { get; set; } // 外键关联所属的DestinationPlan public Guid DestinationPlanId { get; set; } public DestinationPlan DestinationPlan { get; set; } public List<Destination> Destinations { get; set; } = new(); } public class Destination { [Key] public Guid Id { get; set; } = Guid.NewGuid(); public string Name { get; set; } = string.Empty; public TimeSpan EstimatedTime { get; set; } // 外键关联所属的DestinationPlanDay public Guid DestinationPlanDayId { get; set; } public DestinationPlanDay DestinationPlanDay { get; set; } public List<SubDestination> SubDestinations { get; set; } = new(); } public class SubDestination { [Key] public Guid Id { get; set; } = Guid.NewGuid(); public string Name { get; set; } = string.Empty; // 外键关联所属的Destination public Guid DestinationId { get; set; } public Destination Destination { get; set; } } }
2. 创建数据库上下文(DbContext)
DbContext是EF Core和数据库交互的核心,咱创建一个AppDbContext,声明所有实体的DbSet(对应数据库里的表):
using Microsoft.EntityFrameworkCore; using Itinerary.API.Models.Domain; namespace Itinerary.API.Data { public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } // 每个DbSet对应一张数据库表 public DbSet<DestinationPlan> DestinationPlans { get; set; } public DbSet<DestinationPlanDay> DestinationPlanDays { get; set; } public DbSet<Destination> Destinations { get; set; } public DbSet<SubDestination> SubDestinations { get; set; } } }
3. 注册DbContext到项目
打开Program.cs,把DbContext注册到依赖注入容器里,这里用SQL Server做示例,连接字符串从appsettings.json读取:
var builder = WebApplication.CreateBuilder(args); // 注册DbContext,使用SQL Server builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 添加控制器和Swagger(方便测试API) builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 开发环境启用Swagger if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
然后在appsettings.json里添加连接字符串(用LocalDB的话直接用下面的,换成自己的数据库也可以):
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ItineraryDb;Trusted_Connection=True;MultipleActiveResultSets=true" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
4. 写HttpPost API控制器
创建DestinationPlansController,注入AppDbContext,写Post方法接收嵌套对象并存库:
using Microsoft.AspNetCore.Mvc; using Itinerary.API.Data; using Itinerary.API.Models.Domain; namespace Itinerary.API.Controllers { [Route("api/[controller]")] [ApiController] public class DestinationPlansController : ControllerBase { private readonly AppDbContext _context; // 构造函数注入DbContext public DestinationPlansController(AppDbContext context) { _context = context; } [HttpPost] public async Task<IActionResult> CreateDestinationPlan(DestinationPlan plan) { // 把整个嵌套对象添加到数据库上下文 _context.DestinationPlans.Add(plan); // 异步保存所有变更到数据库(EF Core会自动处理嵌套对象的关联和插入) await _context.SaveChangesAsync(); // 返回201 Created状态码,同时返回新创建的资源信息和访问地址 return CreatedAtAction(nameof(GetDestinationPlan), new { id = plan.Id }, plan); } // 可选:加一个Get方法,用来验证数据是否存成功 [HttpGet("{id}")] public async Task<ActionResult<DestinationPlan>> GetDestinationPlan(Guid id) { // 加载所有嵌套层级的数据(Include+ThenInclude) var plan = await _context.DestinationPlans .Include(p => p.DestinationPlanDays) .ThenInclude(d => d.Destinations) .ThenInclude(s => s.SubDestinations) .FirstOrDefaultAsync(p => p.Id == id); if (plan == null) { return NotFound(); } return plan; } } }
5. 生成数据库表(迁移)
用EF Core的迁移功能生成数据库表:
- 打开包管理器控制台(工具 -> NuGet包管理器 -> 包管理器控制台)
- 执行命令:
或者用dotnet CLI命令(终端里执行):Add-Migration InitialCreate Update-Database
执行完后,你的LocalDB里就会生成dotnet ef migrations add InitialCreate dotnet ef database updateItineraryDb数据库和对应的四张表。
6. 测试API
启动项目,访问https://localhost:<你的端口>/swagger,找到DestinationPlans的Post接口,点击Try it out,输入下面的示例JSON:
{ "destinationPlanDays": [ { "date": "2024-05-20", "dayNumber": 1, "destinations": [ { "name": "故宫", "estimatedTime": "03:00:00", "subDestinations": [ { "name": "太和殿" }, { "name": "乾清宫" } ] }, { "name": "景山公园", "estimatedTime": "01:30:00", "subDestinations": [ { "name": "万春亭" } ] } ] } ] }
点击Execute,会返回201状态码和新创建的DestinationPlan数据。然后用Get接口,传入返回的Id,就能看到完整的嵌套数据已经存在数据库里了。
内容的提问来源于stack exchange,提问作者Piotr Deja
相关产品推荐
相关产品推荐

