設計與使用ASP.NET Core Web API 2- Swagger

by vivid 11. 十一月 2020 02:14

.NET Magazine國際中文電子雜誌
作 者:許薰尹
文章編號: N201122401
出刊日期: 2020/11/11

這篇文章是《設計與使用ASP.NET Core Web API》系列的文章中的第二篇,延續《設計與使用ASP.NET Core Web API 1-使用Entity Framework Core存取資料》一文的情境,我們將使用Swagger與Swagger UI描述與測試Web API具備的功能。

使用Swagger描述Web API功能

做為ASP.NET Core Web API的設計者,你需要讓自己或其它程式設計師知道Web API提供了哪些功能以供程式叫用,「Swagger」是個好工具,也稱為「OpenAPI」,「OpenAPI」是一個工業標準的規格,用來描述現代化的REST API,詳細資訊可參閱官網的說明:「https://www.openapis.org/」。

「Swagger」可以為Web API產生文件,提供測試頁面讓你直接測試Web API,不需要再裝額外程式或瀏覽器的擴充套件。要在ASP.NET Core Web API專案中使用「Swagger」需要在專案中安裝「Swashbuckle.AspNetCore」套件,此套件的詳細資訊,可參閱以下網址:「https://github.com/domaindrivendev/Swashbuckle.AspNetCore」。

Swashbuckle.AspNetCore」套件中包含三個主要元件:

  • · 「Swashbuckle.AspNetCore.Swagger」元件:包含「Swagger」物件模型與中介軟體(Middleware)。
  • · 「Swashbuckle.AspNetCore.SwaggerGen」元件:「Swagger」產生器,根據你程式中的路由設定、控制器與模型來建立「SwaggerDocument」物件。
  • · 「Swashbuckle.AspNetCore.SwaggerUI」元件:包含測試ASP.NET Core Web API的圖型介面。

在「Solution Explorer」視窗選取專案名稱,按一下滑鼠右鍵,從選單選取「Manage NuGet Packages」項目,在「NuGet:MyWebAPI」視窗右上方文字方塊中輸入「Swashbuckle.AspNetCore」關鍵字搜尋套件,找到套件之後,從「Version」下拉式清單方塊中選取適當版本之後按「Install」按鈕安裝,參考下圖所示:

clip_image002

圖 1:安裝「Swashbuckle.AspNetCore」套件。

在「Startup」類別「ConfigureServices」方法叫用「AddSwaggerGen」方法來設定「Swagger」中介軟體(Middleware),你可定義一到多個「Swagger」文件(Swagger Document),利用「OpenApiInfo」物件的「Title」屬性設定標題;以及「Version」屬性設定文件的版本,請參考以下程式列表:

  • MyWebAPI\Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MyWebAPI.Models;

namespace MyWebAPI {
  public class Startup {
    public Startup( IConfiguration configuration ) {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices( IServiceCollection services ) {
      services.AddControllers( );
      services.AddDbContext<PubsContext>( options =>
           options.UseSqlServer( "Server=.\\sqlexpress;Database=Pubs;Trusted_Connection=True;" ) );

      services.AddSwaggerGen( gen => {
        gen.SwaggerDoc( "v1.0", new Microsoft.OpenApi.Models.OpenApiInfo {
          Title = "My Web API",
          Version = "v1.0"
        } );
      } );

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure( IApplicationBuilder app, IWebHostEnvironment env ) {
      if ( env.IsDevelopment( ) ) {
        app.UseDeveloperExceptionPage( );
      }

      app.UseHttpsRedirection( );

      app.UseRouting( );

      app.UseAuthorization( );

      app.UseSwagger( );
      app.UseSwaggerUI( ui => {
        ui.SwaggerEndpoint( "/swagger/v1.0/swagger.json", "My Web API Swagger Endpoint" );
      } );

      app.UseEndpoints( endpoints => {
        endpoints.MapControllers( );
      } );
    }
  }
}

 

在「Startup」類別「Configure」方法叫用「UseSwagger」、「UseSwaggerUI」方法啟用「Swagger」中介軟體(Middleware)。叫用「UseSwagger」方法可以讓你顯露出產生的Swagger JSON,讓你透過以下網址「https://localhost:埠號/swagger/v1.0/swagger.json」存取。「UseSwaggerUI」方法則參考這個「/swagger/v1.0/swagger.json」端點來產生互動式的圖型測試介面。

選取Visual Studio 開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。在Visual Studio開發工具,按CTRL+F5執行網站首頁(請注意:埠號可能會依據實際上的操作而有所不同,請修改為實際的埠號),然後在瀏覽器輸入以下網址(URL)

https://localhost:44311/swagger/v1.0/swagger.json

便可以看到產生出來文件,此文件描述了openapi 的版本,以及ASP.NET Core Web API的名稱、版本等描述,並列出ASP.NET Core Web API具備哪些方法可以被叫用,下列程式碼是「swagger.json」部分列表:

  • swagger.json
{
  "openapi": "3.0.1",
  "info": {
    "title": "My Web API",
    "version": "v1.0"
  },
  "paths": {
    "/Stores/GetStores": {
      "get": {
        "tags": [
          "Stores"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Store"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Store"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Store"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/Stores/GetStoreById/{id}": {
      "get": {
        "tags": [
          "Stores"
        ],
//以下略

 

使用Swagger UI圖型介面

在瀏覽器輸入以下網址,便可檢視Swagger UI:

https://localhost:44311/swagger

從中便可看到Swagger UI的圖型介面,提供叫用服務的相關資訊,ASP.NET Core Web API中的每一個「public」方法都會有一個對應的測試介面,執行結果參考如下:

clip_image004

圖 2:使用Swagger UI圖型介面。

舉例來說,點選第一個「/Stores/GetStores」方法,展開此方法的測試介面,按下「Try it out」按鈕,請參考下圖所示:

clip_image006

圖 3:使用Swagger UI圖型介面測試Web API。

接著會出現「Execute」按鈕,點選此按鈕之後,就會叫用Web API,並將取回的結果顯示在下方區塊中,請參考下圖所示:

clip_image008

圖 4:使用Swagger UI圖型介面測試Web API執行結果。

你也可以在「Startup」類別「Configure」方法叫用「UseSwaggerUI」方法時,將「RoutePrefix」設定為空白:

app.UseSwaggerUI( ui => {

ui.SwaggerEndpoint( "/swagger/v1.0/swagger.json", "My Web API Swagger Endpoint" );

ui.RoutePrefix = string.Empty;

} );

這樣的話,存取Swagger UI的URL就是網站根路徑:

https://localhost:44311/

執行結果請參考下圖所示:

clip_image010

圖 5:使用Swagger UI圖型介面。

安裝與使用「NSwagStudio」工具程式

用戶端程式要叫用Web API時,需要透過「HTTPClient」類別,並得手動處理一些序列化、還原序列化物件的動作,這個過程有點煩鎖。幸好這些雜工都可以利用工具程式自動化處理。「NSwagStudio」工具程式將會是你的好幫手,它可以自動產生叫用ASP.NET Core Web API的TypeScript、C#用戶端程式碼,並自動幫你完成上述序列化、還原序列化物件的雜工。詳細資訊可以參閱以下網站的說明:

https://github.com/RicoSuter/NSwag/wiki/NSwagStudio」。

我們可以從這個網頁上方的「Download latest NSwagStudio MSI installer」超連結下載Windows平台的安裝程式「NSwagStudio.msi」,請參考下圖所示:

clip_image012

圖 6:下載「NSwagStudio」工具程式。

執行下載下來的「NSwagStudio.msi」安裝程式直接安裝,請參考下圖所示:

clip_image014

圖 7:執行「NSwagStudio.msi」安裝程式並啟動「NSwagStudio」。

完成後勾選「Launch NSwagStudio」,然後按「Finish」按鈕完成安裝。

clip_image016

圖 8:完成安裝程式並啟動「NSwagStudio」。

在「NSwagStudio」預設的畫面先進行以下設定,請參考下圖所示:

  • · 「Runtime」:選擇適當的.NET Core版本,本文範例使用「NetCore31」版本。
  • · 將「OpenAPI/Swagger Specification」分頁下的「Specification URL:」指定為「Swagger.json」所在的位置,本文範例為「https://localhost:44311/swagger/v1.0/swagger.json」,輸入URL之後按下「Generate local Copy」左下方將會顯示出「Swagger.json」的內容。
  • · 勾選「Outputs」下的「CSharp Client」,以產生C#用戶端程式碼。

在「CSharp Client」分頁「CSharp Client Settings」進行以下設定:

  • · 指定用戶端類別要使用的命名空間(Namespace),以本文範例而言設定為「MyWeb」,後續我們將建立一個名為「MyWeb」的ASP.NET Core 應用程式當用戶端。
  • · 在「Class Name」指定用戶端類別要使用的類別名稱,以本文範例來說設定為「PublisherService」類別。

clip_image018

圖 9:使用「NSwagStudio」產生用戶端程式碼。

完成設定後,若按下「Generate Outputs」按鈕,用戶端程式會直接顯示在視窗之中,請參考下圖所示:

clip_image020

圖 10:產生用戶端類別。

建立ASP.NET Core MVC用戶端網站

接下來我們要建立ASP.NET Core MVC網站來當做叫用ASP.NET Core Web API的用戶端程式。從Visual Studio開發工具「File」-「Add」-「New Project」項目,在現有方案中加入一個新專案,在「Add a New Project」對話盒中,選取「ASP.NET Core Web Application」範本。請參考下圖所示:

clip_image022

圖 11:建立ASP.NET Core Web Application專案。

在「Configure your new project」對話盒中,設定專案名稱與專案存放路徑,然後按下「Create」鍵,請參考下圖所示:

clip_image024

圖 12:設定專案名稱與專案存放路徑。

在「Create a new ASP.NET Core Web Application」對話盒中,確認左上方的清單選取「.NET Core」,右上方的清單ASP.NET Core版本為「ASP.NET Core 3.x」,選取下方的「Web Application(Model – View -Controller)」樣版專案,勾選「Configure for HTTPS」、清除勾選「Enable Docker Support」核取方塊,確定右方的「Authentication」項目設定為「No Authentication」,然後按下「Create」按鈕建立專案,請參考下圖所示:

clip_image026

圖 13:選取下方的Web Application(Model – View -Controller)」樣版專案。

切換到「NSwagStudio」工具,在「CSharp Client」分頁「CSharp Client Settings」的「Output file path」指定用戶端類別程式要儲存的資料夾與檔名,本文範例則是直接設定為「MyWeb」專案的根目錄。接著點選「Generate Files」按鈕,將程式檔案放在指定的資料夾中,請參考下圖所示:

clip_image028

圖 14:產生Web API用戶端類別。

在Visual Studio工具開啟產生出的「PublisherService」類別程式碼,其中使用到了「Newtonsoft.Json」套件中的類別,因此程式下方會出現紅色的蚯蚓,來暗示無法識別「Newtonsoft.Json」套件中相關的類別,請參考下圖所示:

clip_image030

圖 15:「Newtonsoft.Json」套件。

我們只需在專案中安裝「Newtonsoft.Json」套件就可解決這個問題。在「Solution Explorer」視窗選取專案名稱,按一下滑鼠右鍵,從選單選取「Manage NuGet Packages」項目,在視窗右上方文字方塊中輸入「Newtonsoft」關鍵字搜尋套件,找到「Newtonsoft.Json」套件後,從「Version」下拉式清單方塊中選取適當版本之後按「Install」按鈕進行安裝,請參考下圖所示:

clip_image032

圖 16:安裝「Newtonsoft.Json」套件。

在「Startup」設定與使用「HttpClient」

修改專案中的「Startup.cs」檔案,在「ConfigureServices」方法加入以下程式,叫用「IServiceCollection」實體的「AddHttpClient」方法,註冊「HttpClient」,以便在專案中叫用ASP.NET Core Web API。

  • MyWeb\Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MyWeb {
  public class Startup {
    public Startup( IConfiguration configuration ) {
      Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices( IServiceCollection services ) {
      services.AddControllersWithViews( );
      services.AddHttpClient( );
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure( IApplicationBuilder app, IWebHostEnvironment env ) {
      if ( env.IsDevelopment( ) ) {
        app.UseDeveloperExceptionPage( );
      }
      else {
        app.UseExceptionHandler( "/Home/Error" );
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts( );
      }
      app.UseHttpsRedirection( );
      app.UseStaticFiles( );

      app.UseRouting( );

      app.UseAuthorization( );

      app.UseEndpoints( endpoints => {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}" );
      } );
    }
  }
}

 

查詢商店資料

請參考以下程式列表,在ASP.NET Core MVC「MyWeb」專案中預設的「HomeController」類別,利用建構函式注入(DI)「IHttpClientFactory」物件實體,儲存在「_httpClientFactory」變數,接著在「Index」方法中就可以建立「PublisherService」物件,並叫用「GetStoresAsync」方法來叫用Web API取得商店的資料:

  • MyWeb\Controllers\HomeController.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MyWeb.Models;

namespace MyWeb.Controllers {
  public class HomeController : Controller {
    private readonly ILogger<HomeController> _logger;
    private readonly IHttpClientFactory _httpClientFactory;
    public HomeController( ILogger<HomeController> logger, IHttpClientFactory httpClientFactory ) {
      _logger = logger;
      _httpClientFactory = httpClientFactory;
    }

    public async Task<IActionResult> Index( ) {

      PublisherService client =
        new PublisherService( "https://localhost:44311/", _httpClientFactory.CreateClient() );

      ICollection<Store> stores = await client.GetStoresAsync( );

      return View( stores );
    }

    public IActionResult Privacy( ) {
      return View( );
    }

    [ResponseCache( Duration = 0, Location = ResponseCacheLocation.None, NoStore = true )]
    public IActionResult Error( ) {
      return View( new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier } );
    }
  }
}

 

「GetStoresAsync」方法的名稱是根據你在「StoresController」類別「GetStores」方法上方套用「HttpGet」Attribute指定的「GetStores」名稱來決定的,再回顧一下「GetStores」方法程式碼如下:

  • MyWebAPI\Controllers\StoresController.cs

[HttpGet( "GetStores" )]

public async Task<ActionResult<IEnumerable<Store>>> GetStores( ) {

return await _context.Stores.ToListAsync( );

}

建立Index檢視

將游標停留在「StoresController」控制器類別程式設計畫面「Index」方法之中,按一下滑鼠右鍵,從快捷選單選取「Add View」,請參考下圖所示:

clip_image034

圖 17:建立Index檢視。

在「Add New Scaffolded Item」對話盒中選取「Razor View」範本,請參考下圖所示:

clip_image036

圖 18:選取「Razor View」範本。

在「Add Razor View」對話盒中,設定以下選項:

  • · 「View name」:「Index」。
  • · 「Template」:「List」。
  • · 「Model class」:選取「Store」類別。
  • · 勾選「Use a layout page」核取方塊。

然後按下「Add」按鈕。Visual Studio 2019便會在「Views\Home」資料夾下,新增一個「Index.cshtml」檔案,請參考下圖所示:

clip_image038

圖 19:加入「Index」檢視。

因為範本專案中已存在相同檔名的「Index.cshtml」檔案,因此會跳出一個對話盒,提示是否相檔案覆蓋,選取「Yes」,請參考下圖所示:

clip_image040

圖 20:覆蓋「Index.cshtml」檔案。

Visual Studio 2019將會自動產生以下「Index」檢視程式碼:

  • MyWeb\Views\Home\Index.cshtml

@model IEnumerable<MyWeb.Store>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action = "Create"> Create New </a>
</p>
<table class = "table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor( model => model.StorId )
            </th>
            <th>
                @Html.DisplayNameFor( model => model.StorName )
            </th>
            <th>
                @Html.DisplayNameFor( model => model.StorAddress )
            </th>
            <th>
                @Html.DisplayNameFor( model => model.City )
            </th>
            <th>
                @Html.DisplayNameFor( model => model.State )
            </th>
            <th>
                @Html.DisplayNameFor( model => model.Zip )
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor( modelItem => item.StorId )
            </td>
            <td>
                @Html.DisplayFor( modelItem => item.StorName )
            </td>
            <td>
                @Html.DisplayFor( modelItem => item.StorAddress )
            </td>
            <td>
                @Html.DisplayFor( modelItem => item.City )
            </td>
            <td>
                @Html.DisplayFor( modelItem => item.State )
            </td>
            <td>
                @Html.DisplayFor( modelItem => item.Zip )
            </td>
            <td>
                @Html.ActionLink( "Edit", "Edit", new { /* id = item.PrimaryKey */ }) |
                @Html.ActionLink( "Details", "Details", new { /* id = item.PrimaryKey */ }) |
                @Html.ActionLink( "Delete", "Delete", new { /* id = item.PrimaryKey */ })
            </td>
        </tr>
}
    </tbody>
</table>

 

測試與執行

設定ASP.NET Core Web API與ASP.NET Core MVC兩個專案同時執行,點選「Solution Explorer」視窗中的方案檔案,按一下滑鼠右鍵,從快捷選單中選取「Properties」項目,在「Startup Project」分頁,選取「Multiple startup projects」設定兩個專案同時執行,先執行I「MyWeb API」ASP.NET Core Web AP網站,再執行「MyWeb」ASP.NET Core MVC應用程式,然後按下「OK」按鈕,請參考下圖所示:

clip_image042

圖 21:設定兩個專案同時執行。

選取Visual Studio 2019開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯,完成後可以同時執行兩個網站,只要在Visual Studio 2019開發工具,按「CTRL」+「F5」組合鍵來執行網站應用程式,瀏覽器將會印出呼叫ASP.NET Core Web API服務的執行結果,請參考下圖所示:

clip_image044

圖 22:呼叫Web API服務。

Tags:

.NET Magazine國際中文電子雜誌 | ASP.NET Web API | C# | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List