目錄
一:簡單介紹什么是Web api
二:怎么定義的 Post Get Put 和 Delete
三:簡單使用,直接從前台傳遞一個類到后台接收
四:其他獲取值的方式
一:簡單介紹什么是Web api
REST屬於一種設計風格,REST 中的 POST(新增數據),GET(取得數據),PUT(更新數據),DELETE(刪除數據)來進行數據庫的增刪改查,而如果開發人員的應用程式符合REST原則,則它的服務為“REST風格Web服務“也稱的RESRful Web API”。
微軟的web api是在vs2012上的mvc4項目綁定發行的,它提出的web api是完全基於RESTful標准的,完全不同於之前的(同是SOAP協議的)wcf和webService,它是簡單,代碼可讀性強的,上手快的,如果要拿它和web服務相比,我會說,它的接口更標准,更清晰,沒有混亂的方法名稱,有的只有幾種標准的請求,如get,post,put,delete等,它們分別對應的幾個操作,下面講一下:
GET:生到數據列表(默認),或者得到一條實體數據
POST:添加服務端添加一條記錄,記錄實體為Form對象
PUT:添加或修改服務端的一條記錄,記錄實體的Form對象,記錄主鍵以GET方式進行傳輸
DELETE:刪除 服務端的一條記錄
二:怎么定義的 Post Get Put 和 Delete
首先我們從MVC4 的WEB API模板自動創建的演示文件進行分析
從演示的列子,我們可以看到在Action 中沒有使用[HttpGet]、[HttpPost] 等修飾,那究竟它是如何運作的呢
Action 皆以HTTP 動詞開頭Get、Post、Put、Delete ,這個也是剛好符合 webapi的約定的,什么約定呢?
你調用什么類型的方法 ,例如 post 方法,那么他就去 你的所有的 action 里面 去找 以 post 開頭的方法 ,名字可以隨便叫,例如 postToDataBase 等等,只要開頭匹配 就可以了
打個比喻,假設今天服務端收到了一個GET 請求時,會去查找對應的Controller 並且Action 以"Get..." 開頭的方法,舉個例子:GetMembers、GetTime,以此類推,如果我們從jQuery Ajax 發出了一個POST 請求,也會自動對應到以"Post..." 開頭的Action 內,也就是說實際呼叫哪個Controller 的Action 不是利用網址來決定,而是依照HTTP 所送出的請求來決定,這也就是非常典型的REST風格,而在Web API 中也處理了回傳的數據,讓我們看看Get() 這個方法,回傳IEnumerable<T> 的方法,等於我們擁有了強類型。
我們再來看看默認的 api 路由表
這里,只注冊到了controller,沒有到action,因為api的action名稱是有約定的。
webapi大約有這樣的約定: action名稱中有get的,0參數,匹配路由到/控制器 action名稱中有get的,1參數,匹配路由到 /控制器/id action名稱中有post的,0參數,匹配路由到post方式的/控制器 action名稱中有post的,1參數,匹配路由到post方式的/控制器/id
對於返回,可以直接返回一個class,則apicontroller自動根據請求的content-type序列化成xml或者json。具體例子為,用ie打開相應api的url返回的是json,用chrome返回的就是xml。
另外我們可以注意到在Post Put的方法參數有一個關鍵字[ FromBody ],而Get、Delete則沒有。,事實上沒有加[ FromBody ]就默認為[ FromUri ].
[ FromBody ]表示由請求文件本體中取得資料,就像一般表單Post Submit一樣,取得資料的來源是由請求本體中取得,而[ FromUri ]則表示由URI中取得資料,就像在網址列中的所夾帶的參數
在webapi的示范代碼里,Get方法很簡單只有一個id參數的傳入並且是簡單的int型,因此我們可以用 http://localhost/api/Values/1 這樣的請求執行Get(int id)方法,但事實上並非每個請求都只用一個簡單的參數就可以能搞定,有時我們可能需要2個或以上的參數才能傳遞或者是獲取到數據,我們可以到路由里面改為接受兩個參數,分別為{ p1 } & { p2 }
RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "webapi/{controller}/{p1}/{p2}", defaults: new { id = System.Web.Http.RouteParameter.Optional } );
那么對應的 Controller 里面獲取Get的方法需要修改為
public string Get(String p1, String p2) { return p1 + "/" + p2; }
這種方法,雖然比較簡單,但是如果我們的參數更多的時候,還是這樣去修改 路由也是很麻煩的,我們就采用下面的方法,直接傳遞類到后台
四:復雜傳值,直接從前台傳遞一個類到后台接收
我們還是把路由表恢復成以下
4.1 我們先在前台頁面,用post方式,來傳遞一個類的2個值到后台
定義一個簡單的類
我們在前台提交的頁面設置 方式為 post 提交 ,地址就指向我們的 webapi地址
由於我們是通過 Post方式提交的數據,那么后台接收的時候,就是用 FromBody 來進行接收,由於剛好我們傳遞的前台數據就是類的2個字段,那么后台接收的時候,也可以直接用類來接收,webapi會根據類型和字段來幫我們自動加載數據,獲取到值.
如果你這里是用 get 方式進行傳值的,那么這里的 FromBody 就應該換成 FromUri
4.2 用get方式來獲取數據
我直接在前台,用一個超鏈接,里面 指向我們的webapi 並且傳遞2個值,剛好是我們的UserInfo類的2個屬性
4.3 即使我們傳了一個不存在型別里的屬性名稱參數值,也不會引發錯誤,該參數只會被忽略掉
例如,我們修改4.1的例子,在post提交的時候,我們新增加一個 參數,這個參數在后台的 Userinfo類里面是沒有對應的屬性的,我們這樣提交之后,后台接收到值,會自動忽略掉不在類屬性里面的值
4.4 最傳統 通過 request.form 和 request.querystring 的方式的獲取值
我們傳統的在 aspx或者是 一般處理程序里面獲取值是通過 request.querystring和request.form 來獲取到.那么在 webapi里面,則是有些改變

public void Post([FromBody]string value)
{
HttpContextBase context = (HttpContextBase)Request.Properties["MS_HttpContext"];//獲取傳統context
HttpRequestBase request = context.Request;//定義傳統request對象
string name = request.Form["name"];
}
可以通過上面這種強轉的方式獲取,也可以直接
- var context = HttpContext.Current.Request;
WEBAPI中的Request是HttpRequestMessage類型,不能像Web傳統那樣有querystring和from 方法接收參數,而傳統的HttpReqest的基類是HttpReqestBase. 所以這里我們就直接使用(HttpContextBase)Request.Properties["MS_HttpContext"]
五: 前台調用, ajax 來調用
可以參考 http://www.cnblogs.com/lori/p/3555737.html
參考 : http://tech.it168.com/a2012/0606/1357/000001357231_all.shtml
六: 后台調用,后台代碼調用
參考 : http://www.cnblogs.com/joeylee/p/3810721.html
七 : 如果我們想不用 Get/Post/Put/Delete ,怎么定義 ? 簡單,我們自己在方法上打上 接受動詞標簽 HttpPost HttpGet
我們按照 api/{controller}/{id}的格式
比如我們在 xiaoxin 這個 apicontroller 有自己寫的2個方法(注意 他們的參數名是一樣的,方法名 不一樣)
我們想通過get方法來調用其中一個方法 http://localhost:28160/api/xiaoxin/RequestToken
這個時候就會直接報錯 請求的資源不支持 http 方法“GET”
如果說我們使用的方法名稱不是 Get/Post/Put/Delete 的規則時,那么我們就一定要宣告它的接受動詞 (Accept Verb),所以我們可以修改如下代碼:
再次調用其中的一個方法,並且傳遞參數過去
http://localhost:28160/api/xiaoxin/AccessToken?name=joey&pwd=lee
居然直接就報錯了,提示 : 找到了與該請求匹配的多個操作
這里報錯的坑爹原因是: 你以為你剛才那樣寫 url 是在調用 AccessToken方法? 你太天真了,都說了, 我們的webapi是只綁定到 controller 上,而不綁定到 action上的,調用什么方法,完全看你是用的 post 還是get方法,並且是根據action的名字里面有沒有 post和 get 來匹配action的 ,我這里使用url的方式顯然是get方法, 然后 AccessToken?name=joey&pwd=lee 這么一大串,在路由里面實際就是代表了參數id, 當匹配到 controller 里面的時候,發現有2個 HttpGet 的方法, 但是 這2個方法,他們的參數名字都是一模一樣的,所以就提示了, 找到了與該請求匹配的多個操作….
那么如何修改呢?