IT踩坑日常- API格式(x-www-form-urlencoded)

前言

因前陣子在工作上遇到一些特別的廠商遇到了一些特別的例子,讓我心有餘悸希望之後有踩到坑的同仁可以少跌一些坑。

此次主要業務是與廠商做API介接,但對方的
API(Post)-Request的Body是用 x-www-form-urlencoded 格式

1
2
3
4
5
6
單位代碼(dep_id)
總筆數(all_count)
list []:票號約定清單
異動別(tran_code)(A=增加,D=刪除)
票號(tkt_no)
票種(tkt_tp)(01=成人,02=愛心,03=團體)

API(Post)-Response是用Json格式

1
2
3
4
5
6
7
8
9
result: 成功與否(true/false)
all_count:總筆數
list []:票號約定回傳清單
tran_code:異動別(A=增加,D=刪除)
tkt_no:票號
tkt_tp:票種(01=成人,02=愛心,03=團體)
dep_id:單位代碼
date:約定日期/傳輸日期
status:狀態(00=異動成功,01=異動失敗)

過程

在x-www-form-urlencoded 格式中表現的方式是以Key-Value的方式來呈現,與Json把整個資料表達成一個字串的方式不同,在撰寫Request時在前面兩個屬性dep_id/all_count都還沒甚麼問題,,但到了一個Array[Object]的結構時,可能我下的指令也沒有很精確,因為Copilot其實也是回我類似的結構寫法。

  • 我以為的Key-Value表示式
    (C# 撰寫為例)
1
2
3
4
5
6
var req = new Dictionary<string, string>
{
{ "dep_id", request.Bank_Id },
{ "all_count", $"{request.All_Count}" },
{ "list", JsonConvert.SerializeObject(request.List) }
};

我以為的Key-Value表示式是這樣(Postman 測試為例)
IT_Exp_ApiFormatTrap_1

  • 實際上的array[object] Key-Value表示式
    是這樣(C# 撰寫為例)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var req = new Dictionary<string, string> 
    {
    { "dep_id", request.Bank_Id },
    { "all_count", $"{request.All_Count}" }
    };

    var count = 0;
    foreach (var item in request.List)
    {
    req.Add($"list[{count}][{nameof(item.Tran_Code).ToLower()}]", item.Tran_Code);
    req.Add($"list[{count}][{nameof(item.Tkt_No).ToLower()}]", item.Tkt_No);
    req.Add($"list[{count}][{nameof(item.Tkt_Tp).ToLower()}]", item.Tkt_Tp);
    count++;
    };

實際上的array[object] Key-Value表示式是這樣(Postman 測試為例):
IT_Exp_ApiFormatTrap_2

疑點

在撰寫 array[object] 這塊表示式時,浪費了一部分時間,主要是因為在寫這個寫法之前,我還有嘗試另種寫法就是在讀取object的Member值的時候,照理說可以用 item.Tran_Code 或是 item[Tran_Code]的方法來取值,但我不知為何用.(dot)的方式來取值對方的回應是失敗的,這點我深深不解……
如下所示(C# 撰寫為例)

1
2
3
4
5
6
7
8
var count = 0; 
foreach (var item in request.List)
{
req.Add($"list[{count}].{nameof(item.Tran_Code).ToLower()}", item.Tran_Code);
req.Add($"list[{count}].{nameof(item.Tkt_No).ToLower()}", item.Tkt_No);
req.Add($"list[{count}].{nameof(item.Tkt_Tp).ToLower()}", item.Tkt_Tp);
count++;
};

如下所示(Postman 為例)
IT_Exp_ApiFormatTrap_3

結語

以上是近期遇到浪費許多時間的坑,由於我是第一次遇到 x-www-form-urlencoded 的格式輸出,就當作是種學習解決後豁然開朗的感覺,但或許有人會覺得廠商沒提供範例嗎? 對,沒提供範例,請廠商提供也沒有要提供的意思,只是一直回再試試看……
共勉之

參考資料

Send Array as Part of x-www-form-urlencoded Using Postman