Asp.net Web API 2 學習隨手記 (Expression)

Asp.net Web API 2 學習隨手記 (Expression)

在使用 Asp Web API2 Controller with actions, using Entity Framework 時,遇到了一個問題,怎樣才能客製化返回的值(因爲自動生成的 controller 會返回 model 裏所有的屬性)。

比如說:
VS 爲我生成的 workstations model 包含了

  • workStationID(工作臺ID),
  • compID(公司ID),
  • BPID(分部場所ID),
  • descriptionLN(中文描述),
  • descriptionEN(英文描述)

基本屬性,以及其他 model 的 ICollection

  • MEST_SSCCAssignment
  • MEST_SSCCLabelPrintLog

直接 GET api/workstations 會返回想看及不想看的所有數據。實際此時我想看到的只有 workstationID 及 descriptionLN 這兩個屬性。

[{
  "$id":"1","MEST_SSCCAssignment":[],
  "MEST_SSCCLabelPrintLog":[],
  "workStationID":1,
  "compID":"00100",
  "BPID":"10010",
  "descriptionLN":"3樓碼板區,4號樓 (A/E線)",
  "descriptionEN":"3/F Pallet Packing Area,  #4 Building (Line A/E)"
  },{
  "$id":"2","MEST_SSCCAssignment":[],
  "MEST_SSCCLabelPrintLog":[],
  "workStationID":2,
  "compID":"00100",
  "BPID":"10010","descriptionLN":"2樓碼板區,4號樓 (A/E線)",
  "descriptionEN":"2/F Pallet Packing Area,  #4 Building (Line B/F/G)"
}]

在網上搜了一下,似乎沒有類似的需要,要不然就是這個問題太簡單,不值得去記錄。Anyway,反正是沒找到。現在你知道了,這個博客主要是我自己學習的記錄(再好的記憶都不如一隻最便宜的筆和紙)。

於是,我用了一個最土炮的方法,寫了一個類,然後用 foreach 遍歷並用 List 存儲起來,最後用 IHttpActionResult 返回 List

private class tupaoWorkstation
{
    public int workstationId;
    public string descLn;
}

// GET: api/Workstations
public IHttpActionResult GetMESM_WorkStation()
{
    List<tupaoWorkstation> _ws = new List<tupaoWorkstation>();
    foreach (MESM_WorkStation ws in db.MESM_WorkStation)
    {
        tupaoWorkstation temp = new tupaoWorkstation { workstationId = ws.workStationID, descLn = ws.descriptionLN };
        _ws.Add(temp);
    }
    if (_ws.Count == 0) { return NotFound(); }
    return Ok(_ws);
}

這樣,返回的值就乾淨多了有木有

[{
  "$id":"1",
  "workstationId":1,
  "descLn":"3樓碼板區,4號樓 (A/E線)"
  },{
  "$id":"2",
  "workstationId":2,
  "descLn":"2樓碼板區,4號樓 (A/E線)"
}]

再再再後來,在 http://www.asp.net/web-api/overview/web-api-routing-and-actions 上學習怎麼使用 Routing 時,突然發現它裏面給了更高大上的方式來達到上面的目的!那就是用 Expression

怎麼做呢,其實跟土炮方法差不多(至少對我來說),也是需要先創建一個類來存儲最終要提供的信息。統一一個叫法 Dto (Data transfer object)。人家都已經有名字了,我還去傻傻的 Reinvent the wheel 幹啥呢?

於是,我就寫了一個 WorkstationDto 的類,跟上面的土炮 workstation類的內容一樣。然後,重點來了,在 controller 里加上下面這句

private static readonly Expression<Func<MESM_WorkStation, WorkstationDto>> AsWsDto = x => new WorkstationDto
{
    id = x.workStationID,
    descLn = x.descriptionLN
};

然後 GetMESM_WorkStation() 這個 function 就可以簡單的改爲

// GET: api/Workstations
public IQueryable<WorkstationDto> GetMESM_WorkStation()
{
    return db.MESM_WorkStation.Select(AsWsDto);
}

看到沒,只要簡單在生成的代碼後面加上 .Select(AsWsDto) 就可以了(返回的 IQueryable 的 Type 也改爲 WorkstationDto)!比起前面用 foreach 來的簡潔多了。有木有有木有?

當然,返回的值和土炮方法是一樣的。

好了,就這麼多。如果你有幸(或不幸)看到這篇文章,並且有意見的話,就留言吧。如果小編有空的話會回覆你的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章