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 的內建驗證管道以用於最小 API,並配置 Swagger 以便在 API 啟動時自動啟動。 該集涵蓋了從儲存過程到測試端點的完整迴圈,包括 .NET 開箱即用返回的驗證錯誤響應格式。 如果您正在關注 Linux 上的 C# 系列或第一次向最小 API 新增寫入操作,這篇文章將逐步講解每個步驟。

建立插入記錄型別

[1:46 - 4:43] 在構建端點之前,Tim 建立了一個代表插入請求形狀的資料傳輸物件。現有的 TicketModel 包括資料庫自動生成的字段,例如 IdCreatedDate。 在 POST 主體中接受這些會被忽略或導致衝突,因此單獨型別將輸入範圍限定為僅需呼叫者提供的字段。

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

using record 而不是 class 是一個刻意的選擇。記錄預設提供基於值的相等性和不可變性,這符合請求載荷的語義:資料到達、驗證、傳遞到資料庫,且中間從不修改。 三個屬性(標題、描述、優先順序)直接映射到 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 全部端點並執行它。 新票出現在列表中,與原始測試記錄並排。

測試還揭示了沒有驗證的差距:發送空標題、缺少描述或優先順序為 99 都以 204 成功,資料庫接受 API 發送的任何內容。 這種差距促成了下一節的動力。

新增內建驗證

[14:43 - 18:28] 自 .NET 10 起,最小 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] 確保該字段存在且不為空。 [MinLength(1)] 防止空字串通過必填檢查(因為空字串技術上不為空)。 [Range(1, 5)] 將優先順序約束在有效等級中。 這些屬性是 ASP.NET MVC 控制器多年間使用的相同 System.ComponentModel.DataAnnotations 型別,但現在已能在最小 API 中工作,無需額外的中介軟體。

保存並重新啟動後,Tim 發送了一個帶空標題和優先順序為 10 的請求。響應回來是結構化的錯誤主體:

{
    "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 專案的 Properties/launchSettings.json,向 HTTPS 配置檔新增了 launchUrl 屬性:

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

下次啟動時,瀏覽器將直接開啟到 Swagger UI,而不是預設頁面。 這會每次除錯迴圈節省幾秒鐘,並且在整個開發會話中積累起來。

結論

[20:09 - 20:31] 向最小 API 新增 POST 端點涉及建立一個專用的輸入記錄,將其映射到帶有集合 URL 的 MapPost,並將記錄作為參數物件調用儲存過程。 .NET 10 中的驗證需要一個服務註冊和記錄屬性上的標準資料註解屬性。 框架自動處理 400 響應格式化。

系列導航: 本文是 Linux 上的 C# 系列構建 Tiny Ticket 應用的一部分。上一篇:新增 Get By ID 端點。 下一篇:新增 PUT 更新端點

範例提示:當您的插入儲存過程返回新記錄的 ID 時,將返回從 Results.NoContent() 更改為 Results.Created($"/api/tickets/{newId}", result),以便給呼叫者一個帶位置標頭的 201 狀態,他們可以依據該標頭獲取建立的資源。

在他的 YouTube Channel 上觀看完整影片,獲得有關在 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天試用金鑰
無需信用卡或帳戶建立