13天的假期結束,趕忙回來充電了html
本節目錄web
RESTjson
REST是「REpresentational State Transfer」的縮寫,能夠翻譯成「表現狀態轉換」.api
REST是一種軟件架構風格,與技術無關,可是大部分基於REST風格的Web服務都是基於HTTP的瀏覽器
(雖然WCF在3.5之後支持REST,可是WCF太龐大了,Web API更適合作REST架構)多線程
SOAP與REST架構
SOAP Web API採用RPC(面向方法Remote Procedure Call)風格,它採用面向功能的架構,因此在設計之初首先須要考慮的是提供怎樣的功能。併發
RESTful Web API採用ROA(面向資源Resouce Oriented Architecture)架構,因此在設計之初首先須要考慮的是有哪些資源可供操做。app
HTTP協議
HTTP採用簡單的請求/響應模式的消息交換旨在實現針對某個Web資源的某種操做。
至於針對資源的操做類型,不外乎CRUD(Create、Retrieve、Update和Delete)而已。
一個HTTP請求除了利用URI標誌目標資源以外,還須要經過HTTP方法指名針對資源的操做類型。
HTTP方法:包括GET(查)、POST(增)、PUT(改)、DELETE(刪)、HEAD、OPTIONS、TRACE、CONNECTION和PATCH等
HTTP協議
GET http://neverc.cn/ HTTP/1.1 Host: neverc.cn Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.15 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8 Cookie:
第1行是HTTP的3個基本屬性,method,uri,vesion
其餘都是HTTP的請求報頭header,http定義不少原生的header,也能夠添加自定義header(實際就是鍵值對)
除了報頭,一個HTTP請求還能夠包括一個請求主體內容,能夠是任意格式.
與HTTP請求同樣,HTTP響應也是由報頭和報文2部分組成.
HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html; charset=utf-8 Vary: Accept-Encoding Server: Microsoft-IIS/7.5 X-AspNetMvc-Version: 5.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 18 Sep 2015 05:39:50 GMT Content-Length: 12003 <!DOCTYPE html>
第1行是vesion和statu(除了200 OK外,常見的有401 Not Authorized、404 Not Found)
第3行Content-Type表示媒體(或者叫資源/數據)類型.
創建項目
涉及到的引用的程序集
建立實體
在Model項目中,新建一個Contact類
public class Contact { public string Id { get; set; } public string Name { get; set; } }
建立控制器
在WebApi項目中,引用System.Web.Http類庫並建立API控制器
public class ContactsController : ApiController { #region Data static readonly List<Contact> contacts; static int counter = 2; static ContactsController() { contacts = new List<Contact> { new Contact{Id = "001",Name = "張三"}, new Contact{Id = "002",Name = "李四"} }; } #endregion public IEnumerable<Contact> Get(string id = null) { return from contact in contacts where contact.Id == id || string.IsNullOrEmpty(id) select contact; } public void Post(Contact contact) { //多線程併發處理 Interlocked.Increment(ref counter); contact.Id = counter.ToString("D3"); contacts.Add(contact); } public void Put(Contact contact) { contacts.Remove(contacts.First(c => c.Id == contact.Id)); contacts.Add(contact); } public void Delete(string id) { contacts.Remove(contacts.First(c => c.Id == id)); } }
自我寄宿
在SelfHost中,引用System.Web.Http、System.Net.Http、System.Web.Http.SelfHost類庫並實現寄宿
static void Main(string[] args) { //對於SelfHost來講,HttpController類型的解析在默認狀況下只會針對加載到當前應用程序域中的程序集列表 //經過手工加載,讓該程序集加載到當前應用程序域中。 Assembly.Load("WebApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); var configuration = new HttpSelfHostConfiguration("http://localhost/selfhost"); using (var httpServer = new HttpSelfHostServer(configuration)) { httpServer.Configuration.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }); httpServer.OpenAsync().Wait(); Console.WriteLine("寄宿Web API服務成功"); Console.Read(); } }
測試
運行SelfHost控制檯,瀏覽器訪問http://localhost/selfhost。
注意:(因爲此處會註冊http.sys,因此須要管理員身份運行VS)
使用IIS寄宿很是簡單,只要註冊好路由數據便可
創建項目
註冊路由
新建Global文件,註冊HttpRoute
public class Global : HttpApplication { protected void Application_Start(object sender, EventArgs e) { GlobalConfiguration.Configuration.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }); } }
測試
運行WebHost項目,瀏覽器訪問http://~/api/Contacts。
由於Web API是基於HTTP的,因此對於開發人員,就像普通請求網站數據同樣
這裏演示一個HttpClient完整的例子,對於異步有疑問,可閱讀個人博客:[C#] 談談異步編程async await
新建一個控制檯項目便可,實現Program類:
static HttpClient httpClient = new HttpClient(); static void Main(string[] args) { //因爲HttpClient類中的方法大部分爲異步 //Main方法不支持Async關鍵字 //故新建一個方法,使其同步運行 Process(); Console.Read(); } async static void Process() { //獲取當前聯繫人列表 ListContacts(); //添加新的聯繫人 var contact = new Contact { Name = "王五" }; await httpClient.PostAsJsonAsync("http://localhost/selfhost/api/contacts", contact); Console.WriteLine("添加新聯繫人「王五」:"); ListContacts(); //修改現有的某個聯繫人 var response = await httpClient.GetAsync("http://localhost/selfhost/api/contacts/001"); contact = (await response.Content.ReadAsAsync<IEnumerable<Contact>>()).First(); contact.Name = "趙六"; await httpClient.PutAsJsonAsync("http://localhost/selfhost/api/contacts/001", contact); Console.WriteLine("修改聯繫人「001」信息:"); ListContacts(); //刪除現有的某個聯繫人 await httpClient.DeleteAsync("http://localhost/selfhost/api/contacts/002"); Console.WriteLine("刪除聯繫人「002」:"); ListContacts(); } async static void ListContacts() { var response = await httpClient.GetAsync("http://localhost/selfhost/api/contacts"); IEnumerable<Contact> contacts = await response.Content.ReadAsAsync<IEnumerable<Contact>>(); Console.WriteLine("當前聯繫人列表:"); foreach (Contact contact in contacts) { Console.WriteLine("{0,-6}{1,-6}", contact.Id, contact.Name); } Console.WriteLine(); }
Web API借用了MVC的設計,以Controller形式定義服務,Action表明具體的操做.
Web API藉助於URL路由獲得控制器,再根據路由對象,經過http方法找到對應的action.(實際上,若是根據url解析不到action的時候,纔會經過http方法)
路由註冊
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
因爲在模板中沒有定義action,因此只能經過httpmethod來找action.(而且是根據方法前綴匹配便可)
經過瀏覽器api/Contacts查看的時候,會返回一個xml格式的數據.
實際上,webapi是先檢查accept,從左到右,去匹配序列化器,若是沒有匹配到則使用默認的json序列化器.
管道式設計
Web API也採用了管道式設計,這是一個不一樣於MVC的管道.雖然不少地方和MVC類似.
Route對象爲HttpRoute
Handle對象爲HttpControllerHandler(因爲實現了IHttpAsyncHandler接口,因此默認走BeginProcessRequest異步方法)
擴展:
若是你的網站部署在IIS上,直接Nuget下載 Install-Package Microsoft.AspNet.WebApi.WebHost 便可使用Web API
本文地址:http://neverc.cnblogs.com/p/4603935.html
參考:http://www.cnblogs.com/artech/p/how-asp-net-web-api-works.html