跳至页脚内容
Iron Academy Logo
学习 C#
学习 C#

其他类别

在Linux上为.NET Aspire添加PUT更新端点

[[academy-video-youtube({"vid": "hSRI_JKiH5M", "start_time": "0", "title": "在Linux上的.NET Aspire中添加PUT更新端点", "creator": "Tim Corey", "length": "8m 43s"})]]

一旦API能够读取和创建记录,下一步操作就是更新现有的记录。 PUT端点用调用者提供的数据替换整个资源,这意味着请求体需要每个字段,而不仅仅是更改的那些。 PUT(完全替换)和PATCH(部分修改)之间的区别影响到输入类型的设计方式以及调用者与端点的交互方式。

在他的视频"在Linux上的.NET Aspire中添加PUT更新端点"中,Tim Corey将更新端点添加到Tiny Ticket API,创建了一个包含插入记录未包含字段的专用更新记录类型(如ID和完成日期),应用验证属性并通过Swagger测试整个过程。 该集遵循先前章节中建立的相同模式,但引入了一个可为null的DateTime字段以及PUT和PATCH语义之间的区别。 如果您正在Minimal API中构建CRUD端点,此文章覆盖了更新部分。

创建更新记录类型

[1:54 - 4:04] 前一集中的插入记录接受了Title、Description和Priority。 更新记录需要两个额外的字段:正在修改的票据的ID和DateCompleted时间戳。Tim复制了插入记录并进行了调整。

public record TicketUpdateRecord(
    [Required, Range(1, int.MaxValue)] int Id,
    [Required, MinLength(1)] string Title,
    [Required] string Description,
    DateTime? DateCompleted,
    [Range(1, 5)] int Priority
);
public record TicketUpdateRecord(
    [Required, Range(1, int.MaxValue)] int Id,
    [Required, MinLength(1)] string Title,
    [Required] string Description,
    DateTime? DateCompleted,
    [Range(1, 5)] int Priority
);

[Range(1, int.MaxValue)]约束,防止负值或零进入数据库。 DateTime?,因为尚未解决的工单不应要求完成日期。 它不需要验证属性,因为null是一个有效状态。

为了确保记录属性完全匹配,Tim从spTickets_Update存储过程中提取字段列表。 这种对齐允许Dapper直接映射记录,而无需任何手动属性到参数的连接。

映射PUT端点

[4:04 - 5:44] 端点注册遵循既定模式。 /api/tickets路由,处理程序使用更新记录调用存储过程:

app.MapPut("/api/tickets", async Task<Results<NoContent, ValidationProblem>>
    (TicketUpdateRecord ticket, ISqlDataAccess sql) =>
{
    await sql.SaveDataAsync("dbo.spTickets_Update", ticket, "TicketDB");
    return TypedResults.NoContent();
});
app.MapPut("/api/tickets", async Task<Results<NoContent, ValidationProblem>>
    (TicketUpdateRecord ticket, ISqlDataAccess sql) =>
{
    await sql.SaveDataAsync("dbo.spTickets_Update", ticket, "TicketDB");
    return TypedResults.NoContent();
});

Results<NoContent, ValidationProblem>声明为返回类型告诉框架该端点在成功时生成204,在验证失败时生成400。 ValidationProblem变体由先前章节中注册的管道自动处理; 处理程序本身只需要返回成功案例。

值得注意的是Dapper包装器如何保持数据访问简洁:存储过程名称、模型、连接字符串名称。 三个参数涵盖整个数据库调用。 包装器在系列早期编写,并且每个新端点重用它无需修改。

PUT vs. PATCH: 当完全替换重要时

[6:06 - 6:46] 在测试之前,Tim停下来澄清PUT与PATCH之间的区别。 PUT请求替换整个资源:请求体中的每个字段覆盖相应数据库列,即使调用者不打算更改它。 PATCH请求仅更新正文中包含的字段。

对于Tiny Ticket项目,PUT是正确的选择,因为前端将加载完整票据,让用户编辑字段并完整地将对象发送回去。 在生产应用程序中,Tim提到他可能会特别为常见的单字段操作(如标记票据为已完成)添加一个PATCH端点,在这种情况下,仅为翻一个日期而发送整个对象显得浪费。

通过Swagger测试更新

[6:46 - 8:26] Tim launches the API and opens Swagger. 在测试PUT之前,他运行GET all端点以检查数据的当前状态。 一个测试记录(ID 109)在标题、描述和优先级上有空值,这是早期测试的结果。 这成为更新的目标。

他在PUT请求体中填写了ID 109,标题为"Sample Record",描述和优先级为5。执行后,响应返回为204。再次运行GET all确认记录现在有更新后的值。

为了验证验证,他清除了标题字段并再次执行。 响应返回400,带有结构化错误信息:"票据标题字段是必需的。"相同的验证属性从插入端点传递到更新记录,因为它们使用相同的注解模式。

总结:CRUD进展

[8:26 - 8:43] 随着PUT端点的完成,Tiny Ticket API现在涵盖四个CRUD操作中的三个:读取(GET all和GET by ID)、创建(POST)和更新(PUT)。 每个端点都遵循相同的结构模式,这使得代码库可预测。 剩下的操作是DELETE,Tim预告这是下一集的内容。

结论

[8:38 - 8:43] 向简化API添加PUT端点需要一个专用的更新记录,具有验证属性,MapPut注册到集合URL,并通过数据访问包装器调用存储过程。 Results<NoContent, ValidationProblem>返回类型让框架处理成功和验证失败的响应。 像DateTime?这样的可为null字段可以通过而无需验证属性,因为对于未完成的数据,null是一个有效值。

系列导航:本文是Tiny Ticket应用建设过程中Linux上的C#系列的一部分。上一个:添加POST插入端点。 下一个:添加DELETE端点

示例提示:如果您的更新存储过程返回修改行数,请在返回204之前检查它。计数为零意味着ID未匹配任何记录,您应返回404而不是默认为成功。

观看完整视频在他的YouTube频道上,获得更多关于在Linux上的C#系列中构建CRUD端点的见解。

Hero Worlddot related to 在Linux上为.NET Aspire添加PUT更新端点
Hero Affiliate related to 在Linux上为.NET Aspire添加PUT更新端点

分享您的所爱,赚取更多收入

您为使用 .NET、C#、Java、Python 或 Node.js 的开发人员创建内容吗?将您的专业知识转化为额外收入!

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我