[ASP.NET] WebAPI Multiple Parameters Design
在Web API設計上有時我們不見得傳遞一個參數就能滿足需求,在前面二篇文章中(WebAPI Post Mapping 複雜型別 & WebAPI Get 使用複雜型別) 我們也談及到如何使用複雜型別來做為參數的傳遞,這時就能滿足我們有多參數的需求,然而有時候這些參數並不是相互有關聯性,只是因為某些因素不得不要求呼叫端在每次呼叫時傳送必須給予,那麼設計上我們該如何切割呢?
假設情境:呼叫Web API建立一筆員工基本資料
我們會建立一個Web API並傳遞具有一個Employee類別的參數,大致會像下面程式碼這樣
[HttpPost] public void AddEmployee(Employee empobj) { //Do Add Employee }
Employee類別
public class Employee { public String EmpNo { get; set; } public String Name { get; set; } public Employee() { // // TODO: 在這裡新增建構函式邏輯 // } }
接著假設我們因為要記錄呼叫端是來自於什麼設備的呼叫,所以我們會想要記錄設備的一些資訊( 名稱、作業系統、使用語系 ),並且在希望在每次呼叫時都能取得,所以我們建立一個DeviceInfo類別
public class DeviceInfo { public String Name { get; set; } public String OsVersion { get; set; } public String Lang { get; set; } public DeviceInfo() { // // TODO: 在這裡新增建構函式邏輯 // } }
然後直覺上會為Web API加入這個類別參數,形成一個具有二個複雜型別參數的Web API
// POST api/<controller> [HttpPost] public void AddEmployee(Employee empobj,DeviceInfo devobj) { //Do Add Employee }
但很快的您會發現這樣具有二個複雜型別參數的Web API是不能運作的,原因是當傳遞複雜型別時是由請求的message body內容來取得,並由 .Net Framework自動幫我們做了Mapping,而且只支援一個參數。所以接著我們把原本Employee類別納入DeviceInfo類別做為其屬性,就會變成如下
public class Employee { public String EmpNo { get; set; } public String Name { get; set; } public DeviceInfo DevInfo { get; set; } public Employee() { // // TODO: 在這裡新增建構函式邏輯 // } }
這樣Web API就可以維持原本的方式透傳遞Employee類別做為唯一的參數,並可以正常呼叫。
但是 這樣一來Employee類別裡夾帶了原本與Employee無關的屬性並不是一件好事,此外並非每個使用到Employee類別的AP都有記錄呼叫端資訊的需求,這會使得Employee類別變的有些怪異,因此筆者的做法會是多加一層做為Web API專用參數類別,而這個專用參數類別的內容則依需求來組合,以這個例子來說,筆者會建立一個AddEmpWebApiParameter類別做為專用參數類別
public class AddEmpWebApiParameter { public Employee EmpObj { get; set; } public DeviceInfo DevInfo { get; set; } public AddEmpWebApiParameter() { // // TODO: 在這裡新增建構函式邏輯 // } }
而在Web API的部份則調整為
// POST api/<controller> [HttpPost] public void AddEmployee(AddEmpWebApiParameter para) { Employee emp = para.EmpObj; DeviceInfo devinfo = para.DevInfo; //Do Add Employee }
在概念上就是每個類別裡只具有跟自已有關的成員,不去過問外界的使用情境,而外界的需求則以組合的概念來完成,上面的演示過程簡單說明這樣的一個概念,當然在實務上設計還會搭配介面及分層設計來進行,希望這個說明對大家在設計Web API有所幫助,也歡迎有任何建議可以相互討論。
Ref :
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
By No.18