IRONSOFTWAREHOME

在Linux上为.NET Aspire添加带验证的POST插入端点

在Linux上的.NET Aspire中添加带验证的POST插入端点

Tim Corey

20m 31s

从API中读取数据只是故事的一半。 到最后,每个应用程序都需要接收新记录,这意味着构建一个POST端点来接收请求体,验证输入,将它持久化到数据库,并返回一个有意义的状态代码。 在原型开发过程中跳过验证步骤很有诱惑力,但接受未经验证输入的生产API会成为损坏数据的来源,比预防更难清理。

在他的视频"在Linux上的.NET Aspire中添加带验证的POST插入端点"中,Tim Corey为Tiny Ticket API添加了一个插入端点,创建了一个专用的输入记录类型,连接.NET的内置验证管道用于Minimal API,并在API启动时自动配置Swagger启动。 此集涵盖从存储过程到测试端点的完整周期,包括.NET默认返回的验证错误响应格式。 如果您正在关注Linux上的C#系列或首次添加写操作到Minimal API,这篇文章将带您逐步完成每一步。

创建插入记录类型

[1:46 - 4:43] 在创建端点之前,Tim 创建了一个数据传输对象,表示插入请求的结构。现有的CreatedDate等字段。 在POST主体中接受这些内容要么会被忽略,要么会引起冲突,因此一个单独的类型将输入限定为只有调用者应提供的字段。

public record TicketInsertRecord(string Title, string Description, int Priority);
C#

使用class是一个深思熟虑的选择。记录默认提供基于值的等价性和不可变性,这符合请求负载的语义:数据到达、经过验证、传递到数据库,并且在此过程中从不修改。 这三个属性(Title、Description、Priority)直接映射到spTickets_Insert存储过程的参数。

映射POST端点

[4:43 - 9:51] 定义记录类型后,端点注册遵循与GET 路由相同的模式,但使用MapPost并将请求正文绑定到插入记录:

app.MapPost("/api/tickets", async (TicketInsertRecord ticket, IDbConnection db) =>
{
    await db.SaveDataAsync("spTickets_Insert", ticket);
    return Results.NoContent();
});
C#

请注意,路径是/api/tickets,没有ID段,符合REST 约定,其中POST 到集合URL会创建一个新资源。 处理程序调用存储过程,并将整个ticket对象作为参数包传递。 Dapper按名称映射记录的属性到SQL参数。

返回Results.NoContent()发送204状态码。 Tim解释了原因:插入成功,但在响应体中没有任何有意义的内容可以返回。 一些API返回新创建的对象,状态为201 Created,并带有指向新资源的Location头,这是一个有效的替代方案。对于Tiny Ticket项目,204保持简单。

通过Swagger测试插入

[9:51 - 14:43] Tim启动项目并导航到Swagger。 POST端点出现,带有与TicketInsertRecord属性匹配的请求正文模式。 他填写了一个测试票据,其中包含标题、描述和优先级,然后执行请求。

返回了204,确认插入成功。 为了验证数据确实已持久化,他切换到GET all端点并执行它。 新票据出现在列表中,与原始测试记录并列。

测试还揭示了没有验证的差距:发送一个空标题、缺失描述或优先级为99的请求都成功并返回204。数据库接受API发送的任何内容。 这个差距促成了下一节的来临。

添加内置验证

[14:43 - 18:28] 从.NET 10开始,Minimal API支持内置的验证管道,该管道从输入类型读取数据注解属性,在处理程序执行之前拒绝无效请求。 Tim通过两步将其连接起来。

首先,在Program.cs中注册验证服务。 这一行激活整个管道:

builder.Services.AddValidation();
C#

注册服务后,框架会在处理程序运行之前检查每个请求体的验证属性。 第二步是用每个字段必须满足的规则注释插入记录:

public record TicketInsertRecord(
    [Required, MinLength(1)] string Title,
    [Required] string Description,
    [Range(1, 5)] int Priority
);
C#

[Required]确保字段存在且不为null。 [MinLength(1)]防止空字符串通过必要的检查(因为空字符串在技术上不为null)。 [Range(1, 5)]将优先级限制在有效的级别。 这些属性是ASP.NET MVC控制器多年以来使用的相同System.ComponentModel.DataAnnotations类型,但现在无需附加中间件即可在最小API中工作。

保存并重新启动后,Tim发送一个空标题和优先级为10的请求。响应返回为400 Bad Request,带有结构化错误体:

{
    "errors": {
        "Title": ["The Title field is required."],
        "Priority": ["The field Priority must be between 1 and 5."]
    }
}
JSON

验证管道在处理程序运行之前短路请求,因此无效数据不会到达数据库。 错误响应遵循RFC 7807问题详情格式,API消费者可以以编程方式解析。

启动时自动启动Swagger

[19:44 - 20:31]一个小的生活质量提升为这一集结尾。 每次Tim启动API时,他都必须手动在浏览器URL中输入/swagger。 为了自动化这一点,他打开API项目的launchUrl属性:

{
    "profiles": {
        "https": {
            "launchUrl": "swagger"
        }
    }
}
JSON

下一次启动时,浏览器将直接打开Swagger UI而非默认页面。 这节省了调试周期中的几秒钟,这在整次开发会话中累加。

结论

[20:09 - 20:31] 在最小API中添加POST端点涉及创建一个专用的输入记录,将其映射到集合URL的MapPost,并以记录作为参数对象调用存储过程。 .NET 10中的验证需要一个服务注册和记录属性上的标准数据注解属性。 框架会自动处理400响应的格式化。

**系列导航:**本文是Tiny Ticket应用建设过程中Linux上的C#系列的一部分。上一个:添加按ID获取端点。 下一个:添加PUT更新端点

示例提示:当您的插入存储过程返回新记录的ID时,将返回值从Results.Created($"/api/tickets/{newId}", result),以向调用者提供带有位置头的201状态,他们可以跟随该头以获取创建的资源。

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

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户