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 MBmaxRequestLength
: HTTP 請求最大大小(byte),預設 4 MBexecutionTimeout
: 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);
}
第二頁(第二次抓取),nextId
為 97
:
示範:
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)
)
- 作者的設計原理