Web API 框架是一個面向 Http 協議的通信框架。相對於 WCF 而言,Web API 只面向於 Http 協議設計,而且沒有 WCF 那么繁瑣的配置。Web API 的開發類似於 ASP.NET MVC 中控制器的開發,但是相對於直接使用 ASP.NET MVC 來返回 Json 對象的方式而言,Web API 封裝了數據的序列化、反序列化,接口、實現都更加簡單。
簡單地說,如果要向瀏覽器、移動端提供 Json 數據格式的 API,則應該首選 Web API 作為通信框架。
以下,我列出了在當前使用 Web API 開發系統時,遇到的幾個知識點或問題。
數據序列化
Web API 框架目前支持兩種數據格式的序列化:Json 及 Xml。在不做任何配置的情況下,如果 Http 請求中,HttpHeader 中 Accept 被指定為 accept: application/xml,則 Web API 會自動把數據使用 xml 進行序列化,否則使用 json 序列化。
如果期望不使用 xml 序列化數據,我們可以通過 GlobalConfiguration.Configuration.Formatters 來進行配置:config.Formatters.Remove(config.Formatters.XmlFormatter)。
一般情況下,我們會使用 Json 序列化。跟 ASP.NET MVC 的 Json 序列化不同的是,Web API 使用了 Newtonsoft.Json 框架來進行序列化。(例如,JsonMediaTypeFormatter.SerializerSettings 屬性就是 Newtonsoft.Json.JsonSerializerSettings 類型,可以直接對序列化進行配置。)
Json 序列化支持對匿名類型進行進行序列化,這大大方便了開發人員,例如,我們可以隨意組裝數據並直接返回:
1: [HttpGet]
2: public IEnumerable AllGet()
3: {
4: return new string[] { "Item1", "Item2" }.Select(s => new
5: {
6: Name = s,
7: Code = s,
8: Items = new ArrayList
9: {
10: new { Name = "Item1" },
11: new { Name = "Item2" },
12: new { Name = "Item3" },
13: new { Name = "Item4" },
14: }
15: });
16: }
另外,Web API 提供了 HttpResponseMessage 類型可作為返回值,使得開發人員可以對 HttpResponse 做一些更詳細的設置。而且,如果不期望修改返回值類型而直接返回 HttpResponse 時,可以使用 HttpResponseException 間接返回一個 HttpResponseMessage。
Action 匹配
Web API 框架默認是基於 Restful 架構模式的,與 ASP.NET MVC 有區別的是,它會根據 Http 請求的 HttpMethod(Get、Post、Put、Delete) 來在 Controller 中查找 Action,規則是:Action 名中是否以 Get、Post 開頭?Action 上標記 HttpGet、HttpPost 等標記?並會完全忽視 Action 的方法名。
例如,Web API 對於資源的 CRUD 操作,采用如下格式:
get /API/models/ 查詢所有實體
get /API/models/1000 查詢id為1000的實體
post /API/models/ {id:-1, name:'name'} 添加一個實體
put /API/models/ {id:1000, name:'name'} 更新指定實體
delete /API/models/1 刪除指定實體
在面向服務的架構中,往往不會直接把底層的實體公布出來,讓客戶端直接進行 CRU 操作;而是公布一些粗粒度的 RPC 形式的服務操作。要使用 Web API 框架,我們需要修改默認的配置。例如,讓客戶端在調用時顯式指定 action 名稱:
1: config.Routes.MapHttpRoute(
2: name: "DefaultApi",
3: routeTemplate: "api/{controller}/{action}/{id}",
4: defaults: new { id = RouteParameter.Optional }
5: );
這樣,由於顯式指定了 Action 名稱,Web API 會使用該名稱來查找對應的 Action 方法,而不再按照 HttpMethod 約定來查找對應的 Action。例如,對於以下 API 的調用如下:
1: [HttpGet]
2: public HttpResponseMessage Login(string userName, string password)
3: {
4: return Request.CreateResponse(HttpStatusCode.NotFound);
5: }
調用方法:
get /api/account/login/?username=hqf@qq.com&password=dsd
關於 POST 參數綁定
Web API 相對於 ASP.NET MVC,使用了新的參數綁定類。要注意的是,Action 參數列表中只能有一個參數可以從 Http Post Body 中反序列化出來。如果參數列表中只有一個參數,而且它的類型是一個復雜類型,那么 Web API 會直接把 Body 嘗試反序列化為該類的對象。如果有多個參數,那么要從 Body 反序列化的那個參數,需要標記上 [FromBodyAttribute]。
相關內容,比較復雜,可以參考以下文章:
http://www.cnblogs.com/sicket/archive/2012/06/28/2567129.html
http://www.cnblogs.com/lushuicongsheng/archive/2012/10/27/2742214.html
http://www.tuicool.com/articles/eQzyEv
http://weblogs.asp.net/cibrax/archive/2012/08/10/binding-form-data-in-asp-net-web-api.aspx
不錯的示例代碼
MSDN 上有一個比較全面的示例代碼:
http://code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7
本文講得比較淺,只是列舉一些開發過程中會經常遇到的需要注意的點。解決這些問題后,我們的系統,已經開始使用 Web API 來進行開發了。