You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手向:如何在.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包管理器 -> 包管理器控制台)
  • 执行命令:
    Add-Migration InitialCreate
    Update-Database
    
    或者用dotnet CLI命令(终端里执行):
    dotnet ef migrations add InitialCreate
    dotnet ef database update
    
    执行完后,你的LocalDB里就会生成ItineraryDb数据库和对应的四张表。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:36:01