(二)ASP.NET Web API 2 - 建立第一個Web API

我們會在這篇文章中建立一個Web API,包含Model、Controller、Routing以及一個網頁(HTML + jQuery)來呼叫Web API,展現一個完整前後端偕同運作的架構。

文章中,我們會學習建立一個用於撰寫Web API的專案,並設計資料的Model,然後撰寫Controller,再來就是設定相對應的Routing,最後就是用一個標準的HTML的網頁配合jQuery的Ajax技術來呼叫Web API,將資料顯示在網頁上,接下來整個系列,我們都假設要設計一個包括新增、取得、更新及刪除應徵者資料的系統。

第一步:建立一個用於撰寫Web API的專案,環境如下:

  • Visual Studio 2015 community
  • .Net Framework 4.6.1
  • 語言:C#

首先我們選擇"Web"專案範本中的"ASP.NET Web Application (.Net Framework)",並給專案取的名字。

接下來,我們選擇"空白"範本,並在"加入資料夾和核心參考"的地方點選"Web API",Visual Studio會自動把撰寫Web API所需要的資源都附加進專案中。

第二步:建立專案後,Visual Studio會建立好所有需要的資源,包含基本的資料夾,其結構如下圖:

  • App_Data:專案會使用到的資料檔,包含如MDF、XLSX、XML、JSON...等。
  • App_Start:預設在這個資料夾中有一個WebApiConfig.cs檔,他記錄了Web API的Routing設定,工程師也可以在這裡去設計自己的Routing。
  • Controllers:放置控制器的所在地,也就是所有商業邏輯、演算法...等程式放置的地方。
  • Models:定義資料模型、處理資料(操作資料庫、檔案)程式都放在這邊。
  • Global.asax:用於設計回應HTTPModules所對應的應用程式層級事件的程式碼,如設定對應的Routing...等。
  • Web.config:整個專案的設定檔。

第三步:在Models建立一個資料的模型。

在"Models"資料夾上按右鍵,在"加入"一個"類別",並在接下來的視窗中給這個類別一個名字"Candidate.cs"。

在"Candidate.cs"類別中,我們來定義應徵者的資料模型,包含ID、姓名、年紀與E-Mail。

public class Candidate
{
    public string Name { get; set; }        
    public string Id { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

第三步:建立一個取得所有應徵者資料清單的控制器(Controller),

選擇"Web API 2 控制器 - 空白",因為我們要一手打造我們自己的控制器(Controller),來增加我們對技術的熟悉度。

我們給這個控制器(Controller)一個名字,這個命名基本上是沒有規則,隨自己喜好,但通常我們會以對應的Models來設定一個相同的名字,以便日後識別控制器(Controller)與資料模型(Model)的關係。

第四步:接下來我們在控制器(Controller)裡面加入一些資料。

Models.Candidate[] Candidates = new Models.Candidate[] {
    new Models.Candidate { Name="peter", Id="a000000000", Age=30, Email="peter@gmail.com" },
    new Models.Candidate { Name="justin", Id="a11111111", Age=28, Email="justin@gmail.com" },
    new Models.Candidate { Name="terry", Id="a222222222", Age=32, Email="terry@gmail.com" }
};

第五步:同樣在控制器(Controller)中,我們新增兩個方法,一個是取得所有應徵者的資料清單,另一個是取得特定名字的應徵者資料,這邊用到一點LINQ的小技巧,先不要去在意他。

//取得所有應徵者的資料清單
public IEnumerable<Models.Candidate> GetAllCandidates()
{
    return Candidates;
}

//取得特定名稱應徵者的資料
public IHttpActionResult GetCandidate(string Name)
{
    var myCandidate = Candidates.FirstOrDefault((c) => c.Name == Name);
    if (myCandidate == null)
        return StatusCode(HttpStatusCode.NoContent);
    else
        return Ok(myCandidate);
}
  • IEnumerable:代表一個資料集,可以是List、Table...等,在Web API的應用中,我們通常以JSON格式回傳資料給前端。
  • IHttpActionResult:代表一個HTTP的狀態,例如100、200、301、404、500...等,詳細的狀態代碼請參考微軟MSDN的說明

第六步:請開啟App_Start資料夾中的WebApiConfig.cs檔案,我們要來修改一下Routing,因為在上一步的第二個方法,他需要傳入一個參數,所以我們必須在Routing裡面設計一個具有一個名為Name參數的URI,以便被呼叫時能直接被對應到。

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{name}", //新增一個{name}作為傳入參數,代表URI的完整結構
    defaults: new { name = RouteParameter.Optional } //設定name為一個Routing傳入的參數
);

有看到routeTemplate: "api/{controller}/{name}"這段嗎?這裡面有兩個重要的地方:

  • {controller}:這代表在整個URI時他所對應的控制器(Controller)名稱,剛剛我們新增了一個控制器名為"CandidatesController.cs",所以這個控制器就名為"Candidates"。
  • {name}:這是對應到控制器方法的參數,在第五步的第二個方法中,我們必須傳入一個參數,這兩個地方就這樣對應了起來。

所以,按照這個邏輯,routeTemplate: "api/{controller}/{name}"對應到的URI就會是api/candidates/應徵者的名字

第七步:到目前為止已經成功的設計好了兩個ASP.NET Web API了,但到底呼叫這個兩個Web API會回傳什麼樣的資料呢?使用一個常用的測試工具Postman來呼叫Web API,結果如下圖:

呼叫Web API(HTTP GET Method)

該網址會對應到第一個方法,並回傳所有應徵者的資料:

[
  {
    "Name": "peter",
    "Id": "a000000000",
    "Age": 30,
    "Email": "peter@gmail.com"
  },
  {
    "Name": "justin",
    "Id": "a11111111",
    "Age": 28,
    "Email": "justin@gmail.com"
  },
  {
    "Name": "terry",
    "Id": "a222222222",
    "Age": 32,
    "Email": "terry@gmail.com"
  }
]

若改為呼叫(HTTP GET Method)有帶參數的Web API

則會對應到第二個方法,Web API會回傳名為"peter"的應徵者資料:

{
  "Name": "peter",
  "Id": "a000000000",
  "Age": 30,
  "Email": "peter@gmail.com"
}

第八步:知道怎麼呼叫Web API,也知道回傳什麼資料,接下來附上前端的範例,功能很簡單,如下:

  • 顯示所有應徵者資料。
  • 以應徵者姓名帶出對應的資料。

以下就是前端網頁部分的程式碼:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
    <title>Candidates</title>
    <meta charset="utf-8" />
    <script>
        var apiurl = 'api/candidates';
        $(document).ready(function () {
            GetAllCandidates();
        });

        function GetAllCandidates() {
            $.ajax({
                url: apiurl,
                success: function (result) {
                    $('#divCandidates').empty();
                    $.each(result, function (key, item) {
                        $('<li>' + item.Name + ', ' + item.Id + ', ' + item.Age + ', ' + item.Email + '</li>').appendTo('#divCandidates');
                    });
                }
            });
        }

        function SearchCandidate() {
            var name = $('#candidateName').val();
            $.ajax({
                url: apiurl + '/' + name,
                success: function (result) {
                    $('#divCandidates').empty();
                    $('<li>' + result.Name + ', ' + result.Id + ', ' + result.Age + ', ' + result.Email + '</li>').appendTo('#divCandidates');
                },
                error: function (jqXHR, exception) {
                    $('#divCandidates').empty();
                    alert('Nothing');
                }
            });
        }

    </script>
</head>
<body>
    <div>
        <h2>Candidates</h2>
        <p>
            Name:<input id="candidateName" type="text" />
            <input type="button" value="Search" onclick="SearchCandidate();" />
        </p>
        <p id="divCandidates"></p>
    </div>
</body>
</html>

最後,附上完整的範例專案檔,以便更全面、直觀的學習撰寫ASP.NET Web API。

範例下載連結:ASP.NET Web API 2 Practics01