Advanced usage of Web API Helper

ExtApiHelper 不僅能簡化建立回應物件的流程,也能方便地解析請求中的資訊並且進行處理

Table of Contents

Get Request Info

以下示範如何取得從客戶端的請求中各種資訊

示範:

// GET api/values/100?name=Tony
public HttpResponseMessage Get(int id)
{
    ExtApiHelper api = new ExtApiHelper(this);
    string MyHost = api.getMyHost();                      // 客戶端請求時的 host 
    string YourIP = api.getIP();                          // 客戶端的 IP
    string YourUserAgent = api.getUserAgent();            // 客戶端使用的 UserAgent
    string MyCookieValue = api.getCookie("MyCookie");     // 取出 Cookie 中的 MyCookie 數值
    string MyHeaderValue = api.getHeader("MyHeader");     // 取出 Header 中的 MyHeader 數值 
    string QueryName = api.getQuery("name");              // 取出 QueryString 中的 name 數值
    return api.getResponse(new
    {
        MyHost,
        YourIP,
        YourUserAgent,
        MyCookieValue,
        MyHeaderValue,
        QueryName,
        id,
    });
}

輸出:

{
    "MyHost": "http://localhost:61256",
    "YourIP": "::1",
    "YourUserAgent": "PostmanRuntime/7.2.0",
    "MyCookieValue": "123456",
    "MyHeaderValue": null,
    "QueryName": "Tony",
    "id": 100
}

Receive JSON Body

以下示範客戶端以 JSON 方式傳送資料的接收方式

請求:

  • URI:POST /api/Values/
  • Content-Type:application/json
  • Raw Data:
{
    "name": {
        "FirstName" : "Wang",
        "LastName" : "Tony"
    }
}

設計對應的 Model 承接資料

示範:

// 外層 Model
class ModelData 
{
    public ModelName name { get; set; }
}
// 裡層 Model
class ModelName
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

使用 Model 承接 JSON 格式的資料

示範:

public HttpResponseMessage Post()
{
    ExtApiHelper api = new ExtApiHelper(this);

    // 從 Body 中取出 JSON 資料,並填充到 Model
    ModelData body = api.getJsonBody<ModelData>();

    return api.getResponse(new {
        name = body.name.LastName + body.name.FirstName
    });
}

輸出:

{
    "name": "TonyWang"
}

Uploading File

以下示範客戶端以 multipart/form-data 方式傳送檔案與資料的接收方式

設定 Web.Config

  • Storage: 檔案上傳後的儲存位置
  • MaxUploadFileSize: 上傳最大檔案大小(byte),預設 5 MB
  • maxRequestLength: HTTP 請求最大大小(byte),預設 4 MB
  • executionTimeout: HTTP 請求最長等待時間(秒),預設 110 秒
<appSettings>
    <add key="Storage" value="C:\Storage"/>
    <add key="MaxUploadFileSize" value="5242880"/> 
</appSettings>

<system.web>
    <httpRuntime executionTimeout="300" maxRequestLength="5242880"/>
</system.web>

重要 !!:確認專案目錄下有 App_Data 目錄, 該目錄是檔案處理的暫存目錄,如果沒有該目錄請新增它

接下來就可以將檔案上傳至 Storage 目錄下,並取得檔案相關的資訊

請求格式

  • URI: /api/upload
  • Content-Type: multipart/form-data; boundary=...
  • Form: message=123456
  • Form: file=....

示範:

[Route("upload")]
public HttpResponseMessage upload()
{
    ExtApiHelper api = new ExtApiHelper(this);

    string name = null;
    long size = 0;
    string type = null;
    string des = null;

    List<ModelFile> files = api.uploadFile(); // 上傳檔案 !!!

    foreach (ModelFile file in files) // 取得檔案訊
    {
        name = file.name; // 新的檔案名稱
        size = file.size; // 檔案大小 (byte)
        type = file.type; // 檔案的 MIME Type
        des = file.des;   // 檔案原始名稱
    }

    ModelData data = api.getFormBody<ModelData>();  // 使用自訂的 Model 取得 Form 中的其他資料
    string message = data.message;              

    return api.getResponse(new
    {
        name,
        size,
        type,
        des,
        message
    });
}

輸出:

{
    "name": "58a7b9c7-a967-4c72-bd23-6172ae5abd0c_123.jpg",
    "size": 32736,
    "type": "image/jpeg",
    "des": "123.jpg",
    "message": "123456"
}

注意事項:

  • 新的檔案名稱會自動以 GUID 隨機給予
  • 檔案將儲存於 Storage + file.name (新檔案名稱) 位置

SQL Paging Data

當使用 SQL 抓取大量資料時,可能需要批次給予客戶端資料(分頁),分頁輔助函式使用 Identity (primary key) 作為分頁的基準,他將協助你組合出相應的資料存取 SQL 語法,達成這個效果

設定 Web.Config

  • APIDataLimit: 每個分頁取得資料筆數
<appSettings>
    <add key="APIDataLimit" value="3"/>
</appSettings>

接下來我們將以這個 SQL 語法作為示範

select cid,cname,since from class where cid>10

以下示範了第一次抓取資料的方式

示範:

ExtApiHelper api = new ExtApiHelper(this);
string sql1 = "select cid,cname,since from class where cid>10";
// api.addIdentityPaging(SQL語句,排序欄位與方式,識別子欄位名稱)
api.addIdentityPaging(ref sql1, "since desc", "cid");

Console.WriteLine(sql1); // 輸出

輸出:

select top(4) cid,cname,since from class where cid>10 order by since desc
cid cname since
100 Book 2018-07-20 0:0:0
99 Apple 2018-07-19 0:0:0
98 Fruit 2018-07-18 0:0:0
97 Prok 2018-07-17 0:0:0

此時請注意,預設抓取 n 筆資料(在 Web.config 中設定 APIDataLimit ),但 addIdentityPaging 會抓取 n+1 筆資料,目的是為了判斷是否還能翻下一頁,請自行刪除最後一筆資料並取得最後一筆資料的 ID,作為下一次翻頁的基準

示範:

SQL db = new SQL();
ModelEntity[] data = db.quickQuery<ModelData>(sql);

if(data.Length > int.Parse(Config.get("APIDataLimit")))
{
    // 取出最後一筆的 ID
    string nextId = data[data.Length - 1].cid.ToString(); // 97
    // 刪除最後一筆資料
    Array.Resize(ref data, data.Length - 1); 
}

第二頁(第二次抓取),nextId97

示範:

ExtApiHelper api = new ExtApiHelper(this);
string sql2 = "select cid,cname,since from class where cid>10";
// api.addIdentityPaging(SQL語句,排序欄位與方式,識別子欄位名稱,最後一筆資料ID)
api.addIdentityPaging(ref sql2, "since desc", "cid", "97");
Console.WriteLine(sql2); // 輸出

輸出:

with tb as(
    select 
        ROW_NUMBER() over(order by since desc) as _seq,
        cid,
        cname,
        since 
    from 
        class 
    where cid>10
) 
select top(4) * from tb where _seq>=(select _seq from tb where cid='97') 
order by since desc
cid cname since
97 Pork 2018-07-17 0:0:0
96 Soup 2018-07-16 0:0:0
95 Tea 2018-07-15 0:0:0
94 Noodle 2018-07-14 0:0:0

注意事項

  • 欄位名稱 _seq 為保留字,請勿使用
  • 如果回傳資料筆數大於指定的筆數,表示還有下一頁
    • 將最後一筆資料的 id 取出,以利下一頁的資料取得
    • 請自行移除回傳結果中的最後一筆資料 (可以使用 Array.Resize(ref array, array.Length - 1) )
  • 作者的設計原理

More

results matching ""

    No results matching ""