MVC4 WebAPI(一)

來源:互聯網
上載者:User

標籤:

http://www.cnblogs.com/wk1234/archive/2012/04/28/2468491.html

 

不管是因為什麼原因,結果是在新出的MVC中,增加了WebAPI,用於提供REST風格的WebService,個人比較喜歡REST風格的WebService,感覺比SOAP要輕量級一些,而且對用戶端的要求也更少,更符合網路資料轉送的一般模式,用戶端完全擺脫了代理和管道來直接和WebService進行互動,具體的區別可以參見Web 服務編程,REST 與 SOAP

(一)環境準備

原生環境是XP+VS2010,需要安裝VS2010 SP1升級包,MVC4升級包,Vs2010安裝SP1後會影響SQLServer2008的自動提示功能,需要在安裝補丁或外掛程式,安裝成功後可以建立如下的 MVC WebAPI 項目

(二)概覽

新產生的WebAPI項目和典型的MVC項目一樣,包含主要的Models,Views,Controllers等檔案夾和Global.asax檔案


Views對於WebAPI來說沒有太大的用途,Models中的Model主要用於儲存Service和Client互動的對象,這些對象預設情況下會被轉換為Json格式的資料進行傳輸,Controllers中的Controller對應於WebService來說是一個Resource,用於提供服務。和普通的MVC一樣,Global.asax用於配置路由規則

(三)Models

和WCF中的資料契約形成鮮明對比的是,MVC WebAPI中的Model就是簡單的POCO,沒有任何別的東西,如,你可以建立如下的Model

    public class TestUseMode    {        public string ModeKey{get;set;}        public string ModeValue { get; set; }            }

注意:Model必須提供public的屬性,用於json或xml還原序列化時的賦值

(四)Controllers

MVC WebAPI中的Controllers和普通MVC的Controllers類似,不過不再繼承於Controller,而改為繼承API的ApiController,一個Controller可以包含多個Action,這些Action響應請求的方法與Global中配置的路由規則有關,在後面結束Global時統一說明

(五)Global

預設情況下,模板內建了兩個路由規則,分別對應於WebAPI和普通MVC的Web請求,預設的WebAPI路由規則如下

1             routes.MapHttpRoute(2                 name: "DefaultApi",3                 routeTemplate: "api/{controller}/{id}",4                 defaults: new { id = RouteParameter.Optional }5             );

可以看到,預設路由使用的固定的api作為Uri的先導,按照微軟官方的說法,用於區分普通Web請求和WebService的請求路徑:

Note: The reason for using "api" in the route is to avoid collisions with ASP.NET MVC routing. That way, you can have "/contacts" go to an MVC controller, and "/api/contacts" go to a Web API controller. Of course, if you don‘t like this convention, you can change the default route table.

可以看到,預設的路由規則只指向了Controller,沒有指向具體的Action,因為預設情況下,對於Controller中的Action的匹配是和Action的方法名相關聯的:

具體來說,如果使用上面的路由規則,對應下面的Controller:

    public class TestController : ApiController    {        public static List<TestUseMode> allModeList = new List<TestUseMode>();        public IEnumerable<TestUseMode> GetAll()        {            return allModeList;        }        public IEnumerable<TestUseMode> GetOne(string key)        {            return allModeList.FindAll((mode) => { if (mode.ModeKey.Equals(key)) return true; return false; });        }        public bool PostNew(TestUseMode mode)        {            allModeList.Add(mode);            return true;        }        public int Delete(string key)        {            return allModeList.RemoveAll((mode) => { if (mode.ModeKey == key) return true; return false; });        }        public int DeleteAll()        {            return allModeList.RemoveAll((mode) => { return true; });        }        public int PutOne(string key, string value)        {            List<TestUseMode> upDataList = allModeList.FindAll((mode) => { if (mode.ModeKey == key) return true; return false; });            foreach(var mode in upDataList)            {                mode.ModeValue = value;            }            return upDataList.Count;        }    }

 

則,會有下面的對應關係:

簡單使用JS調用上面提供的資料介面

 1         function getAll() { 2             $.ajax({ 3                 url: "api/Test/", 4                 type: ‘GET‘, 5                 success: function (data) { 6                     document.getElementById("modes").innerHTML = ""; 7                     $.each(data, function (key, val) { 8                         var str = val.ModeKey + ‘: ‘ + val.ModeValue; 9                         $(‘<li/>‘, { html: str }).appendTo($(‘#modes‘));10                     });11                 }12             }).fail(13             function (xhr, textStatus, err) {14                 alert(‘Error: ‘ + err);15             });16         }17 18 19 20         function add() {21 22             $.ajax({23                 url: "api/Test/",24                 type: "POST",25                 dataType: "json",26                 data: { "ModeKey": document.getElementById("txtKey").value, "ModeValue": document.getElementById("txtValue").value },27                 success: function (data) {28                     getAll();29                 }30             }).fail(31             function (xhr, textStatus, err) {32                 alert(‘Error: ‘ + err);33             });34 35         }36 37         function find() {38             39             $.ajax({40                 url: "api/Test/" + document.getElementById("txtFindKey").value,41                 type: ‘GET‘,42                 success: function (data) {43                     document.getElementById("modes").innerHTML = "";44                     $.each(data, function (key, val) {45                         var str = val.ModeKey + ‘: ‘ + val.ModeValue;46                         $(‘<li/>‘, { html: str }).appendTo($(‘#modes‘));47                     });48                 }49             }).fail(50             function (xhr, textStatus, err) {51                 alert(‘Error: ‘ + err);52             });53         }54 55         function removeAll() {56             $.ajax({57                 url: "api/Test/",58                 type: ‘DELETE‘,59                 success: function (data) {60                     document.getElementById("modes").innerHTML = "";61                     getAll();62                 }63             }).fail(64             function (xhr, textStatus, err) {65                 alert(‘Error: ‘ + err);66             });67         }68 69         function remove() {70             $.ajax({71                 url: "api/Test/"+document.getElementById("txtRemoveKey").value,72                 type: ‘DELETE‘,73                 success: function (data) {74                     document.getElementById("modes").innerHTML = "";75                     getAll();76                 }77             }).fail(78             function (xhr, textStatus, err) {79                 alert(‘Error: ‘ + err);80             });81         }82 83         function update() {84             $.ajax({85                 url: "api/Test/",86                 type: ‘PUT‘,87                 dataType: "json",88                 data: { "key": document.getElementById("txtUpdateKey").value, "value": document.getElementById("txtUpdateValue").value },89                 success: function (data) {90                     document.getElementById("modes").innerHTML = "";91                     getAll();92                 }93             }).fail(94             function (xhr, textStatus, err) {95                 alert(‘Error: ‘ + err);96             });97         }

這樣就實現了最基本的CRUD操作。

(六)路由規則擴充

和普通的MVC一樣,MVC WebAPI支援自訂的路由規則,如:在上面的操作中,路由規則使用

"api/{controller}/{id}"

則限定了使用GET方式利用URL來傳值時,controller後面的接收參數名為id,但是在Controller中,GetOne方法的接收參數名為key,是不會被匹配的,這是只需要新增一個新的路由規則,或修改原先的路由規則為:

"api/{controller}/{key}"

當然,可以對路由進行更深的擴充,如:擴充成和普通MVC一樣的路由:

"api/{controller}/{action}/{id}"

這樣,就要求同時使用Action和HTTP方法進行匹配
當然,根據微軟的說法,這種使用是不被推薦的,因為這不符合大家對WebService的一般認知:

For a RESTful API, you should avoid using verbs in the URIs, because a URI should identify a resource, not an action.

(七)使用Attribute聲明HTTP方法

有沒有感覺預設的使用方法名來匹配HTTP Method的做法很傻??或者我有一些方法是自己用的,不想暴露出來,又該怎麼辦?還是使用attribute做這些工作感覺優雅一些,比如,上面的Action我可以更改為:

        [HttpGet]        public IEnumerable<TestUseMode> FindAll()        [HttpGet]        public IEnumerable<TestUseMode> FindByKey(string key)        [HttpPost]        public bool Add(TestUseMode mode)        [HttpDelete]        public int RemoveByKey(string key)        [HttpDelete]        public int RemoveAll()        [HttpPut]        public int UpdateByKey(string key, string value)       [NonAction]         public string GetPrivateData()

當然,我只列出了方法名,而不是這些方法真的沒有方法體...方法體是不變的,NoAction表示這個方法是不接收請求的,即使以GET開頭。
如果感覺常規的GET,POST,DELETE,PUT不夠用,還可以使用AcceptVerbs的方式來聲明HTTP方法,如:

        [AcceptVerbs("MKCOL", "HEAD")]        public int UpdateByKey(string key, string value)        {            List<TestUseMode> upDataList = allModeList.FindAll((mode) => { if (mode.ModeKey == key) return true; return false; });            foreach(var mode in upDataList)            {                mode.ModeValue = value;            }            return upDataList.Count;        }

******************************************************************************
王坤 
出處:http://www.cnblogs.com/wk1234
本文著作權歸 王坤和部落格園共有,歡迎轉載,但請註明出處。

MVC4 WebAPI(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.