練習 - 使用 XML 註解和註釋,自訂和延伸 OpenAPI 文件
在本練習中,您會將註解與註釋新增至程式碼,以擴充開發人員可查看的 API 相關文件。 首先,讓我們來看看預設的 Swagger UI。
在瀏覽器中瀏覽至
http://localhost:5000/swagger
,以檢查 Swagger UI 中 API 端點的 OpenAPI 定義。 當您選取 Get 方法時,應該會看到與下方類似的輸出。Swagger UI 提供一些有關 API 的實用資訊。 其會顯示您可以呼叫的方法 (在您的簡單範例中,則是一個稱為 PriceFrame 的方法)。 您可看到這是一項 HTTP Get 作業,其採用兩個名為 [高度] 和 [寬度] 的必要參數。 您可選取 [歡迎試用],輸入 [高度] 和 [寬度] 值,然後選取 [執行],以查看作用中的 API 呼叫。
API 使用者的資訊仍然不足,因此無法知道 PriceFrame 方法的限制。 我們可以透過 XML 註解,提供一些詳細資訊來幫助他們。
將 XML 註解新增至 API
回到您在上一個練習中使用的 Visual Studio Code 執行個體。
如果 Web API 仍在上一個練習中執行,請在 Windows 上按 ctrl+c,或在 Mac 上按 cmd+c 將它停止。
若要在專案中啟用 XML 文件,請更新 PrintFramerAPI.csproj 專案檔,並將
GenerateDocumentationFile
標籤新增至現有的<PropertyGroup>
並設為true
。<PropertyGroup> <TargetFramework>net7.0</TargetFramework> <GenerateDocumentationFile>true</GenerateDocumentationFile> <NoWarn>$(NoWarn);1591</NoWarn> </PropertyGroup>
在 Startup.cs 中,新增下列 using 陳述式。
using System.Reflection; using System.IO;
在 Startup.cs 的
ConfigureServices
中,將呼叫更新為AddSwaggerGen()
,以告知 Swashbuckle 要使用 XML 文件。public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // Register the Swagger generator, defining 1 or more Swagger documents services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "PrintFramer API", Description = "Calculates the cost of a picture frame based on its dimensions.", TermsOfService = new Uri("https://go.microsoft.com/fwlink/?LinkID=206977"), Contact = new OpenApiContact { Name = "Your name", Email = string.Empty, Url = new Uri("https://zcusa.951200.xyz/training") } }); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); }
在上述程式碼中,反映決定要載入 XML 註解的 XML 檔案名稱。
在 Controllers 資料夾中,開啟 PriceFrameController.cs。 在
GetPrice
方法的 HttpGet 屬性上方,新增下列 XML 註解區塊。 透過在區段標題新增描述,對動作新增三斜線註解,可增強 Swagger UI。/// <summary> /// Returns the price of a frame based on its dimensions. /// </summary> /// <param name="Height">The height of the frame.</param> /// <param name="Width">The width of the frame.</param> /// <returns>The price, in dollars, of the picture frame.</returns> /// <remarks> The API returns 'not valid' if the total length of frame material needed (the perimeter of the frame) is less than 20 inches and greater than 1000 inches.</remarks> [HttpGet("{Height}/{Width}")] public string GetPrice(string Height, string Width) { string result; result = CalculatePrice(Double.Parse(Height), Double.Parse(Width)); return $"The cost of a {Height}x{Width} frame is ${result}"; }
若要儲存所有變更,並確定它是在本機建置,請在 Visual Studio Code 終端機視窗中執行下列命令。
dotnet build
若要查看您的變更,請在 Visual Studio Code 終端機視窗中輸入下列命令,以在本機執行 ASP.NET 應用程式:
dotnet run
再次查看位於
http://localhost:5000/swagger
的 Swagger UI,並注意由您的 XML 註解向 OpenAPI 文件提供的新增資訊。
將資料註解新增至 API
若要啟用 Swagger 以改善 OpenAPI 文件,您可以使用 Microsoft.AspNetCore.Mvc
命名空間中的屬性。
如果 Web API 仍在上一個練習中執行,請在 Windows 上按 ctrl+c,或在 Mac 上按 cmd+c 將它停止。
若要顯示
GetPrice
API 支援 text/plain 的內容類型回應,請在 API 控制器 PriceFrameController.cs 中,於GetPrice
定義上方新增[Produces("text/plain")]
屬性。[HttpGet("{Height}/{Width}")] [Produces("text/plain")]
[Response Content Type] (回應內容類型) 下拉式清單會選取此內容類型作為控制器的 GET 動作預設。
將 Swashbuckle 註釋新增至 API
到目前為止,當 API 能計算指定畫框尺寸的價格,會傳回狀態碼 200。 在 GetPrice
方法的描述中,請注意會有無法計算價格的情況。
告知開發人員回應類型與錯誤碼的較穩健方法,即為透過下列 XML 註解與資料註解。 Swashbuckle 和 Swagger 工具會使用這些值,以清楚產生預期 HTTP 回應碼的 OpenAPI 描述。
也會更新 HTTP 動詞命令篩選建構函式以包含 Name
屬性,並包含 OpenAPI operationId
值。
將下列 using 陳述式新增至 PriceFrameController.cs 檔案。
using Microsoft.AspNetCore.Http;
在 PriceFrameController.cs 中,以下列程式碼與註解取代
GetPrice
。/// <summary> /// Returns the price of a frame based on its dimensions. /// </summary> /// <param name="Height">The height of the frame.</param> /// <param name="Width">The width of the frame.</param> /// <returns>The price, in dollars, of the picture frame.</returns> /// <remarks> /// Sample request: /// /// Get /api/priceframe/5/10 /// /// </remarks> /// <response code="200">Returns the cost of the frame in dollars.</response> /// <response code="400">If the amount of frame material needed is less than 20 inches or greater than 1000 inches.</response> [HttpGet("{Height}/{Width}", Name=nameof(GetPrice))] [Produces("text/plain")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult<string> GetPrice(string Height, string Width) { string result; result = CalculatePrice(Double.Parse(Height), Double.Parse(Width)); if (result == "not valid") { return BadRequest(result); } else { return Ok($"The cost of a {Height}x{Width} frame is ${result}"); } }
此程式碼更新會進行下列變更:
- 此方法會使用
BadRequest()
和Ok()
方法分別建立 BadRequest (400) 和 OK 狀態,以字串結果傳遞給回應。 - XML 註解會描述此方法傳回的每個狀態碼。
- HttpGet 屬性包含
Name
屬性,以發出 OpenAPIoperationId
參數。 - ProducesResponseType 屬性會列出動作傳回的不同回應。 這些屬性會結合 XML 註解 (如先前所述),以在所產生 Swagger 中的各個回應納入易讀描述
- 此方法會使用
使用下列命令重建 Web API:
dotnet build
使用下列命令執行 ASP.NET 應用程式:
dotnet run
在
http://localhost:5000/swagger
中再次查看 Swagger UI,並注意由這些註釋提供的新增資訊。 您 API 的最終 Swagger UI 將顯示於下圖中。
在本練習中,您會擴充開發人員接收到的 API 相關資訊,使其更便於取用。