【前言】html
本文是大雜燴,意思便是:處處Copy再加一點點思考而混在一塊兒的文章,引用來源由於太多太雜故而省略,望原做者原諒。前端
【概述】web
ASP.NET Web API隨ASP.NET MVC 4一塊兒發行。它遵循REST架構風格,取WCF Web API與ASP.NET MVC精華,又去除WCF自己較爲繁瑣的配置問題,專一於提供HTTP Service,只面向Http通訊協議,使得可快速開發出自身使用或對外公開的Web API。前端應用只要能發出HTTP的URI請求(例如:http://domain/api/products)向Web API請求服務便可取得如JSON或XML或自定義數據源。 數據庫
ASP.NET Web APIWeb API 的開發相似於 ASP.NET MVC 中控制器的開發,可是Web API 封裝了數據的序列化、反序列化,接口、實現都更加簡單。 簡單地說,若是要向瀏覽器、移動端等普遍的客戶端提供 Json/xml 數據格式,則應首選 ASP.NET Web API。api
從 .NET 3.5 開始 WCF 框架已經支持用 WebHttpBinding 構建創建在 WCF Message 棧上的 RESTful Web服務。由於 REST 的工做原理不一樣,不須要依賴 SOAP 協議,所以 WCF 消息管道對它作了特殊的優化。但 REST 集成在 WCF 消息管道上仍是不理想,因此微軟提出在 ASP.NET 平臺上構建REST,也就有了如今中的 Web Api。數組
【入門】瀏覽器
一、首先確保開發環境符合微軟的要求:服務器
二、新建Web API項目架構
圖一、建立項目框架
圖2.選擇Web API項目模板
三、添加一個模型
模型是表示應用程序數據的一種對象。ASP.NET Web API能夠自動把模型序列化成JSON、XML、或某些其它格式而後寫到HTTP響應的消息體中。只要客戶端可以讀取這種序列化格式,它就能夠進行反序列化獲取對象信息。另外一方面,設置HTTP請求消息中的Accept報頭,客戶端可以指示它所但願的是哪種格式。
圖3.添加模型
將這個類命名爲「Product」,並添加以下屬性:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace HelloWebAPI.Models { public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } } }
四、添加控制器
控制器是一種處理HTTP請求的對象。「新項目」嚮導在建立該項目時爲你建立了兩個控制器。要看到它們,在「解決方案資源管理器」中展開Controllers文件夾。
HomeController 是傳統的ASP.NET MVC控制器。它負責對網站的HTML頁面進行服務,且與Web API無直接關係。
ValuesController 是一個例子型的WebAPI控制器。在下一步以前,將此控制器徹底刪除。
圖4.添加一個控制器
圖5.建立一個API控制器
修改此控制器的代碼以下:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using HelloWebAPI.Models; namespace HelloWebAPI.Controllers { public class ProductsController : ApiController { Product[] products = new Product[] { new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } }; public IEnumerable<Product> GetAllProducts() { return products; } public Product GetProductById(int id) { var product = products.FirstOrDefault((p) => p.Id == id); if (product == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } return product; } public IEnumerable<Product> GetProductsByCategory(string category) { return products.Where( (p) => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase)); } } }
爲了保持示例簡單,產品被存儲在該控制器類的一個固定數組中。固然,在一個實際應用程序中,你會查詢一個數據庫,或使用某些其它外部數據源。
該控制器定義了三個方法,它們或者返回一個單一產品,或一個產品列表:
GetAllProducts方法以IEnumerable<Product>類型返回產品的完整列表。
GetProductById方法經過ID查詢一個單一產品
GetProductsByCategory方法返回指定類別的所有產品。
好了,你有了一個能工做的Web API了。該控制器上的每一個方法都映射到一個URI(如表1所示):
Controller Method 控制器方法 |
URI |
---|---|
GetAllProducts | /api/products |
GetProductById | /api/products/id |
GetProductsByCategory | /api/products/?category=category |
【調試】
在VS中啓動調試。ASP.NET開發服務器(ASP.NET Development Server)將啓動,屏幕的右下角部將出現一個通知,顯示它運行的端口號。默認地,開發服務器選擇隨機端口號。
Visual Studio而後將自動打開瀏覽器窗口,其URL指向http//www.localhost:xxxx/,這裏,xxxx是端口號。首頁看上去應當像這樣(如圖6所示):
圖6.應用程序首頁
該首頁是一個ASP.NET MVC視圖,它是由HomeControllers類返回的。爲了調用Web API,咱們必須使用前面列出的URI之一。例如,要獲得所有產品列表,瀏覽http://localhost:xxxx/api/products/。
結果取決於你所使用的瀏覽器。Internet Explorer(IE瀏覽器)將提示你是否打開或保存一個名稱爲products的「文件」(如圖7所示)。
圖7.IE的提示
用記事本打開:
若是用Firefox或者Chrome訪問,則會在瀏覽器中用xml形式顯示:
出現這種差異的緣由是IE和Firefox發送了不一樣的Accept報頭,所以,Web API在響應中發送了不一樣的內容類型。
如今,試着瀏覽這些URI:
第一個應當返回ID等於1的詞條。第二個應當返回Category等於「hardware」的全部產品的列表(這裏,只有一個詞條)。
目前爲止就實現了一個最簡單的Web API應用。
有兩個改進的方向:
在IE上按「F12」啓動開發人員工具,能夠看見詳細的請求以及響應信息;
在頁面增長按鈕、輸入框等實現查詢等功能;
以上兩步詳見:調用與 Javascript 和 jQuery 的 Web API的最後部分;
【進階】
一、實現CURD
CURD 是指對資源的增刪查改,對應了Create 、 Update 、 Read 、 Delete 四個簡單的數據庫操做。
在Web API中,Create 、 Update 、 Read 、 Delete 分別能夠經過Post,Put,Delete,Get四種HTTP方法來實現。固然,在實際應用中,更多的是使用了Get/Post方法。
在Web API中,默認在每一個方法名字以前加上Create 、 Update 、 Read 、 Delete字眼就能夠識別方法對應的HTTP方法,當讓,也能夠手動在每一個方法以前增長屬性標註,強制指明所使用的HTTP方法。以下所示:
[HttpGet] [ActionName("GetUser")] public IEnumerable<User> GetUsersByName(string userName) { return users.Where( (p) => string.Equals(p.UserName, userName, StringComparison.OrdinalIgnoreCase)); } [HttpPost] [ActionName("AddUser")] public User AddUser([FromBody]User user) { if (user == null) { throw new HttpRequestException(); } users.Add(user); return user; }
至於ActionName標註,是方便在更改路由規則以後,能夠指定一個URL訪問的動做名字。
二、API路由規則
Web API會App_Start目錄的WebApiConfig.cs文件建立一個默認的路由模板是「api/{controller}/{id}」:
routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
在這個模板中,「api」是一個標記式的文字路徑,而{controller}和{id}是佔位符變量。
當Web API接收到一個HTTP請求,它會試圖根據路由表中的一個路由模板來匹配其URI。若是無路由匹配,客戶端會接收到404(NotFound)錯誤。例如,如下URI與默認路由匹配:
然而,如下URI不匹配,由於它缺乏「api」片斷:
注:使用「api」的緣由是爲了不與ASP.NET MVC的路由衝突。經過這種方式,能夠用「/contacts」進入一個MVC控制器,而「/api/contacts」進入一個Web API控制器。
一旦匹配路由,Web API便會選擇相應的控制和動做:
1,根據URI中的「控制器」做爲{controller}變量的值找到Web API中的Controller。
2,爲了找到動做,Web API尋找一個名稱以HTTP方法名開頭的動做。例如,對於一個GET請求,Web API會查找一個以「Get…」開頭的動做,如「GetContact」或「GetAllContacts」等。這種約定僅運用於GET、POST、PUT和DELETE方法。經過把註解屬性運用於控制器,你能夠啓用其它HTTP方法。也可使用上述所說在每一個方法前增長屬性標註強制指明HTTP方法類型。
3,路由模板中的其它佔位變量,如{id},被映射成動做參數。
正如前文說,較多的HTTP請求使用Get/POST方法,這樣的話,就不排除在一個Controller裏面有好幾個POST方法而且參數格式也差很少的。因爲默認路由只會匹配第一個匹配的方法,因此僅僅是使用默認路由是知足不了要求的。
這種狀況下咱們能夠改變路由規則:
routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } );
配合ActionName,NonAction標註,能夠更改更精準地匹配到方法。
public class ProductsController : ApiController { [HttpGet] [ActionName("Thumbnail")] public HttpResponseMessage GetThumbnailImage(int id); [HttpPost] [ActionName("Thumbnail")] public void AddThumbnailImage(int id); // Not an action method. // 不是一個動做方法 [NonAction] public string GetPrivateData() { ... } }
【發佈】
【推薦網站】
ASP.NET Web API系列教程目錄【對微軟官方主頁教程的良心翻譯】