轉載-Web API 入門

An Introduction to ASP.NET Web API

目前感受最好的Web API入門教程javascript

 HTTP狀態碼html

Web API 強勢入門指南vue

Install Mongodbjava

Getting Started with ASP.NET Web API 2jquery

 

下面的轉自:http://www.cnblogs.com/developersupport/p/aspnet-webapi.htmlweb

Web API是一個比較寬泛的概念。這裏咱們提到Web API特指ASP.NET Web API。ajax

這篇文章中咱們主要介紹Web API的主要功能以及與其餘同類型框架的對比,最後經過一些相對複雜的實例展現如何經過Web API構建http服務,同時也展現了Visual Studio構建.net項目的各類強大。mongodb

目錄

什麼是 Web API

官方定義以下,強調兩個關鍵點,便可以對接各類客戶端(瀏覽器,移動設備),構建http服務的框架。數據庫

ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.json

Web API在ASP.NET完整框架中地位以下圖,與SignalR一塊兒同爲構建Service的框架。Web API負責構建http常規服務,而SingalR主要負責的是構建實時服務,例如股票,聊天室,在線遊戲等實時性要求比較高的服務。

Picture20

 

爲何要用 Web API

Web API最重要的是能夠構建面向各類客戶端的服務。另外與WCF REST Service不一樣在於,Web API利用Http協議的各個方面來表達服務(例如 URI/request response header/caching/versioning/content format),所以就省掉不少配置。

Picture2

 

當你遇到如下這些狀況的時候,就能夠考慮使用Web API了。

  • 須要Web Service可是不須要SOAP
  • 須要在已有的WCF服務基礎上創建non-soap-based http服務
  • 只想發佈一些簡單的Http服務,不想使用相對複雜的WCF配置
  • 發佈的服務可能會被帶寬受限的設備訪問
  • 但願使用開源框架,關鍵時候能夠本身調試或者自定義一下框架

功能簡介

Web API的主要功能

1. 支持基於Http verb (GET, POST, PUT, DELETE)的CRUD (create, retrieve, update, delete)操做

    經過不一樣的http動做表達不一樣的含義,這樣就不須要暴露多個API來支持這些基本操做。

2. 請求的回覆經過Http Status Code表達不一樣含義,而且客戶端能夠經過Accept header來與服務器協商格式,例如你但願服務器返回JSON格式仍是XML格式。

3. 請求的回覆格式支持 JSON,XML,而且能夠擴展添加其餘格式。

4. 原生支持OData

5. 支持Self-host或者IIS host。

6. 支持大多數MVC功能,例如Routing/Controller/Action Result/Filter/Model Builder/IOC Container/Dependency Injection。

Web API vs MVC

你可能會以爲Web API 與MVC很相似,他們有哪些不一樣之處呢?先上圖,這就是他們最大的不一樣之處。

Picture1

詳細點說他們的區別,

  • MVC主要用來構建網站,既關心數據也關心頁面展現,而Web API只關注數據
  • Web API支持格式協商,客戶端能夠經過Accept header通知服務器指望的格式
  • Web API支持Self Host,MVC目前不支持
  • Web API經過不一樣的http verb表達不一樣的動做(CRUD),MVC則經過Action名字表達動做
  • Web API內建於ASP.NET System.Web.Http命名空間下,MVC位於System.Web.Mvc命名空間下,所以model binding/filter/routing等功能有所不一樣
  • 最後,Web API很是適合構建移動客戶端服務

Web API vs WCF

發佈服務在Web API和WCF之間該如何取捨呢?這裏提供些簡單地判斷規則,

  • 若是服務須要支持One Way Messaging/Message Queue/Duplex Communication,選擇WCF
  • 若是服務須要在TCP/Named Pipes/UDP (wcf 4.5),選擇WCF
  • 若是服務須要在http協議上,而且但願利用http協議的各類功能,選擇Web API
  • 若是服務須要被各類客戶端(特別是移動客戶端)調用,選擇Web API

Web API 實戰 (Web API + MongoDB + knockoutjs)

ASP.NET網站上有不少簡單的Web API實例,看看貼圖和實例代碼你就明白怎麼用了。這裏咱們經過一個稍微複雜一點的實例來展現下Web API的功能。

涉及技術

在咱們的實例裏面用到了:

服務URI Pattern

Action Http verb URI
Get contact list GET /api/contacts
Get filtered contacts GET /api/contacts?$top=2
Get contact by ID GET /api/contacts/id
Create new contact POST /api/contacts
Update a contact PUT /api/contacts/id
Delete a contact DELETE /api/contacts/id

準備工做

1. 下載並安裝Mongo DB,步驟看這裏

2. Mongo DB C# driver下載能夠在nuget搜索mongocsharpdriver。

3. 若是想本地察看數據庫中內容,下載MongoVUE

4. Knockoutjs下載能夠在nuget搜索knockoutjs。

代碼實現

1. 建立項目

建立MVC4 Web Application

1

在Project Template中選擇Web API

2

而後項目就建立成了,Controllers裏面有一個ValuesController,是自動生成的一個最簡單的Web API Controller。

正如咱們前面所說,裏面引用的是System.Web.Http命名空間。

3

2. 建立model

在model裏面添加Contact類

4

代碼以下,其中BsonId須要mongocsharpdriver。

1
2
3
4
5
6
7
8
9
public class Contact
     {
         [BsonId]
         public string Id { get ; set ; }
         public string Name { get ; set ; }
         public string Phone { get ; set ; }
         public string Email { get ; set ; }
         public DateTime LastModified { get ; set ; }
     }

咱們須要添加mongosharpdriver。

7

8

另外咱們須要在Model中添加Repository,Controller經過該類來訪問Mongo DB。

1
2
3
4
5
6
7
public interface IContactRepository {
         IEnumerable GetAllContacts();
         Contact GetContact( string id);
         Contact AddContact(Contact item);
         bool RemoveContact( string id);
         bool UpdateContact( string id, Contact item);  
     }

ContactRepository的完整實現以下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class ContactRepository : IContactRepository
     {
         MongoServer _server = null ;
         MongoDatabase _database = null ;
         MongoCollection _contacts = null ;
 
         public ContactRepository( string connection)
         {
             if ( string .IsNullOrWhiteSpace(connection))
             {
                 connection = "mongodb://localhost:27017" ;
             }
 
             _server = new MongoClient(connection).GetServer();
             _database = _server.GetDatabase( "Contacts" );
             _contacts = _database.GetCollection( "contacts" );
 
             // Reset database and add some default entries
             _contacts.RemoveAll();
             for ( int index = 1; index < 5; index++)
             {
                 Contact contact1 = new Contact
                 {
                     Email = string .Format( "test{0}@example.com" , index),
                     Name = string .Format( "test{0}" , index),
                     Phone = string .Format( "{0}{0}{0} {0}{0}{0} {0}{0}{0}{0}" , index)
                 };
                 AddContact(contact1);
             }
         }
 
         public IEnumerable GetAllContacts()
         {
             return _contacts.FindAll();
         }
 
         public Contact GetContact( string id)
         {
             IMongoQuery query = Query.EQ( "_id" , id);
             return _contacts.Find(query).FirstOrDefault();
         }
 
         public Contact AddContact(Contact item)
         {
             item.Id = ObjectId.GenerateNewId().ToString();
             item.LastModified = DateTime.UtcNow;
             _contacts.Insert(item);
             return item;
         }
 
         public bool RemoveContact( string id)
         {
             IMongoQuery query = Query.EQ( "_id" , id);
             WriteConcernResult result = _contacts.Remove(query);
             return result.DocumentsAffected == 1;
         }
 
         public bool UpdateContact( string id, Contact item)
         {
             IMongoQuery query = Query.EQ( "_id" , id);
             item.LastModified = DateTime.UtcNow;
             IMongoUpdate update = Update
                 .Set( "Email" , item.Email)
                 .Set( "LastModified" , DateTime.UtcNow)
                 .Set( "Name" , item.Name)
                 .Set( "Phone" , item.Phone);
             WriteConcernResult result = _contacts.Update(query, update);
             return result.UpdatedExisting;
         }
     }

3. 添加Controller

右鍵Controllers目錄選擇添加Controller

5

選擇Empty API controller,將Controller命名爲ContactsController

6

添加以下代碼,能夠看到Controller中的API方法名就是以http verb命名的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ContactsController : ApiController
     {
         private static readonly IContactRepository _contacts = new ContactRepository( string .Empty);
 
         public IQueryable Get()
         {
             return _contacts.GetAllContacts().AsQueryable();
         }
 
         public Contact Get( string id)
         {
             Contact contact = _contacts.GetContact(id);
             if (contact == null )
             {
                 throw new HttpResponseException(HttpStatusCode.NotFound);
             }
 
             return contact;
         }
 
         public Contact Post(Contact value)
         {
             Contact contact = _contacts.AddContact(value);
             return contact;
         }
 
         public void Put( string id, Contact value)
         {
             if (!_contacts.UpdateContact(id, value))
             {
                 throw new HttpResponseException(HttpStatusCode.NotFound);
             }
         }
 
         public void Delete( string id)
         {
             if (!_contacts.RemoveContact(id))
             {
                 throw new HttpResponseException(HttpStatusCode.NotFound);
             }
         }
     }

4. 添加View

首先添加Knockoutjs庫,

9

Knockoutjs經過MVVM模式來實現動態html綁定數據,以下圖,其中View-Model是客戶端的javascript object保存的model數據。

webapi_ef16

先打開HomeController,裏面添加一個新的Action代碼以下,由於咱們要在MVC中對於ContactsController添加對應的View。

1
2
3
4
5
6
7
public ActionResult Admin()
         {
             string apiUri = Url.HttpRouteUrl( "DefaultApi" , new { controller = "contacts" , });
             ViewBag.ApiUrl = new Uri(Request.Url, apiUri).AbsoluteUri.ToString();
 
             return View();
         }

而後右鍵Admin方法,選擇添加View

10

選擇Create strongly-typed view,在model class中選擇Contact類。

11

添加View的完整代碼,注意view中咱們經過js去訪問WebAPI,以及經過動態綁定將數據呈如今網頁上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
@model WebAPIDemo.Models.Contact
 
@{
     ViewBag.Title = "Admin";
}
 
@section Scripts {
   @Scripts.Render("~/bundles/jqueryval")
   < script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.3.0.js")"></ script >
   < script type="text/javascript">
       function ProductsViewModel() {
           var self = this;
           self.products = ko.observableArray();
 
           var baseUri = '@ViewBag.ApiUrl';
 
           self.create = function (formElement) {
               // If valid, post the serialized form data to the web api
               $(formElement).validate();
               if ($(formElement).valid()) {
                   $.post(baseUri, $(formElement).serialize(), null, "json")
                       .done(function (o) { self.products.push(o); });
               }
           }
 
           self.update = function (product) {
               $.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product });
           }
 
           self.remove = function (product) {
               // First remove from the server, then from the UI
               $.ajax({ type: "DELETE", url: baseUri + '/' + product.Id })
                   .done(function () { self.products.remove(product); });
           }
 
           $.getJSON(baseUri, self.products);
       }
 
       $(document).ready(function () {
           ko.applyBindings(new ProductsViewModel());
       })
   </ script >
}
 
< h2 >Admin</ h2 >
< div class="content">
     < div class="float-left">
     < ul id="update-products" data-bind="foreach: products">
 
         < li >
             < div >
                 < div class="item">ID</ div > < span data-bind="text: $data.Id"></ span >
             </ div >
             < div >
                 < div class="item">Name</ div >
                 < input type="text" data-bind="value: $data.Name"/>
             </ div >
             < div >
                 < div class="item">Phone</ div >
                 < input type="text" data-bind="value: $data.Phone"/>
             </ div >
             < div >
                 < div class="item">Email</ div >
                 < input type="text" data-bind="value: $data.Email"/>
             </ div >
             < div >
                 < div class="item">Last Modified</ div > < span data-bind="text: $data.LastModified"></ span >
             </ div >
             < div >
                 < input type="button" value="Update" data-bind="click: $root.update"/>
                 < input type="button" value="Delete Item" data-bind="click: $root.remove"/>
             </ div >
         </ li >
     </ ul >
     </ div >
 
     < div class="float-right">
     < h2 >Add New Product</ h2 >
     < form id="addProduct" data-bind="submit: create">
         @Html.ValidationSummary(true)
         < fieldset >
             < legend >Contact</ legend >
             @Html.EditorForModel()
             < p >
                 < input type="submit" value="Save" />
             </ p >
         </ fieldset >
     </ form >
     </ div >
</ div >

接下來在_layout.cshtml中添加一個admin頁面的連接以下

1
2
3
4
5
6
< ul id="menu">
     < li >@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null)</ li >
     < li >@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</ li >
     < li >@Html.ActionLink("Admin", "Admin", "Home")</ li >
 
</ ul >

5. 測試與調試

大功告成,直接運行下咱們的做品,咱們的admin連接也顯示在右上角,

12

Admin頁面的樣子,Contact list是動態加載進來的,能夠經過這個頁面作添加,修改,刪除的操做。

13

經過IE network capture來查看請求內容,

從新加載頁面,能夠看到回覆的格式爲JSON,

14

JSON內容就是咱們mock的一些數據。

image

接下來咱們修改,刪除,又添加了一條記錄,能夠看到使用了不一樣的http method。

image

經過前面安裝的mongovue來查看下DB種的數據,先添加的user也在其中,令我感到欣慰。。。

image

相關文章
相關標籤/搜索