有時候我們可能不想顯示某個實體中的所有欄位。比如客戶端發出如下請求:
locaohost:43321/api/groups/1/items?fields=id
locaohost:43321/api/groups/1/items?fields=id,name
以上,對於Item這個類,我們可能只想顯示id,也有可能是想顯示id和name,等等。
如何實現呢?
→ 後端接受fields這個查詢字串的值,split到陣列或集合中
→ 遍歷這些欄位,使用反射獲取欄位的值,並把每個鍵值儲存起來
假設有如下的領域:
public class Group { public int Id{get;set;} public int UserId{get;set;} public string Title{get;set;} public string Descritpion{get;set;} public int StatusId{get;set;} public ICollection<Item> Items{get;set;} } public class Item { public int Id{get;set;} public string Name{get;set;} }
針對Item的控制器如下:
public class ItemsController : ApiController { [Route("groups/{groupId}/items", Name="ItemsForGroup")] public IHttpActionResult Get(int groupId, string fields = null) { List<string> lstOfFields = new List<string>(); if(fields != null) { lstOfFields = fields.ToLower().Split('').ToList(); } var result = _repo.GetItems() .ToList() .Select(e => ItemFactory.CreateDataShapedObject(e, lstOfFields)); return Ok(result); } } public staic class ItemFactory { public object CreateDataShapedObject(Item item, List<string> lstOfFields) { if(!lstOfFields.Any()) { return item; } else { //執行時物件 ExpandObject objectToReturn = new ExpandObject(); foreach(var field in lstOfFields) { //獲取欄位值 var fieldValue = item.GetType() .GetProperty(field, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) .GetValue(item, null); ((IDictionary<string, object>)objectToReturn).Add(field, fieldValue); } return objectToReturn; } } }
以上,ExpandObject是執行時物件,實現IDictionary<string, object>介面,通過反射,把欄位作為ExpandObject的key,把欄位值作為ExpandObject的value。