转载-Web API 入门
An Introduction to ASP.NET Web API
目前感觉最好的Web API入门教程
Getting Started with ASP.NET Web API 2
下面的转自:http://www.cnblogs.com/developersupport/p/aspnet-webapi.html
Web API是一个比较宽泛的概念。这里我们提到Web API特指ASP.NET Web API。
这篇文章中我们主要介绍Web API的主要功能以及与其他同类型框架的对比,最后通过一些相对复杂的实例展示如何通过Web API构建http服务,同时也展示了Visual Studio构建.net项目的各种强大。
目录
什么是 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.
Web API在ASP.NET完整框架中地位如下图,与SignalR一起同为构建Service的框架。Web API负责构建http常规服务,而SingalR主要负责的是构建实时服务,例如股票,聊天室,在线游戏等实时性要求比较高的服务。
为什么要用 Web API
Web API最重要的是可以构建面向各种客户端的服务。另外与WCF REST Service不同在于,Web API利用Http协议的各个方面来表达服务(例如 URI/request response header/caching/versioning/content format),因此就省掉很多配置。
当你遇到以下这些情况的时候,就可以考虑使用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很类似,他们有哪些不同之处呢?先上图,这就是他们最大的不同之处。
详细点说他们的区别,
- 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的功能。
涉及技术
在我们的实例里面用到了:
- Mongo DB数据库保存数据 (NoSQL, Document Store,跨平台,跨语言)
- Web API提供数据服务
- MVC作数据展示
- Knockoutjs动态绑定客户端数据,这里有一个简单的介绍
服务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
在Project Template中选择Web API
然后项目就创建成了,Controllers里面有一个ValuesController,是自动生成的一个最简单的Web API Controller。
正如我们前面所说,里面引用的是System.Web.Http命名空间。
2. 创建model
在model里面添加Contact类
代码如下,其中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。
另外我们需要在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)) { } _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
选择Empty API controller,将Controller命名为ContactsController
添加如下代码,可以看到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库,
Knockoutjs通过MVVM模式来实现动态html绑定数据,如下图,其中View-Model是客户端的javascript object保存的model数据。
先打开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
选择Create strongly-typed view,在model class中选择Contact类。
添加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链接也显示在右上角,
Admin页面的样子,Contact list是动态加载进来的,可以通过这个页面做添加,修改,删除的操作。
通过IE network capture来查看请求内容,
重新加载页面,可以看到回复的格式为JSON,
JSON内容就是我们mock的一些数据。
接下来我们修改,删除,又添加了一条记录,可以看到使用了不同的http method。
通过前面安装的mongovue来查看下DB种的数据,先添加的user也在其中,令我感到欣慰。。。
转载-Web API 入门的更多相关文章
- Web API 入门指南 - 闲话安全
Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...
- Web API入门指南(安全)转
安全检测的工具站点:https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools Web API入门指南有些朋友回复问了些 ...
- 【ASP.NET Web API教程】1 ASP.NET Web API入门
原文 [ASP.NET Web API教程]1 ASP.NET Web API入门 Getting Started with ASP.NET Web API第1章 ASP.NET Web API入门 ...
- Web API 入门指南
Web API 入门指南 - 闲话安全2013-09-21 18:56 by 微软互联网开发支持, 231 阅读, 3 评论, 收藏, 编辑 Web API入门指南有些朋友回复问了些安全方面的问题,安 ...
- Web API 入门 二 媒体类型
还是拿上面 那篇 Web API 入门 一 的那个来讲 在product类中加一个时间属性
- (转)Web API 入门指南 - 闲话安全
原文地址:http://www.cnblogs.com/developersupport/p/WebAPI-Security.html Web API入门指南有些朋友回复问了些安全方面的问题,安全方面 ...
- Web APi入门之Self-Host寄宿及路由原理 【转载】
前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...
- Web Api 入门实战 (快速入门+工具使用+不依赖IIS)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...
- Web APi入门之移除XML格式(一)
前言 回头想来,没想到自己却坚持下来了,EntityFramework系列终于全部完成了,给自己点个赞先.本系列将着手于Web API,关于一些基础的介绍及定义就不再叙述,请参考园友们文章,非常详细, ...
随机推荐
- .NET学习记录2
前面回忆了一些C#基础语法,简单整理了一下笔记,要想深入研究的话,那就得找一本比较好的书了.接下来继续回忆C#语法知识. 方法 功能:用来复用代码的.当我们在一个程序 中反复的写了同样的代码,那么一般 ...
- 使用jquery的imagecropper插件做用户头像上传 兼容移动端
在移动端开发的过程中,或许会遇到对图片裁剪的问题.当然遇到问题问题,不管你想什么方法都是要进行解决的,哪怕是丑点,难看点,都得去解决掉. 图片裁剪的jquery插件有很多,我也测试过很多,不过大多数都 ...
- opencv的学习笔记1
想在周末去游泳,找了些游泳的注意事项什么的,想想还没干正事,就来继续看看opencv的使用吧,晚上看了opencv的一些基本入门的东西,打算下面主要总结CSDN上一个大牛的博文,链接如下:http:/ ...
- SSIS Error The Execute method on the task returned error code 0x80131621
Error Message: The Execute method on the task returned error code 0x80131621 (Mixed mode assembly is ...
- Dynamics AX 2012 R2 配置E-Mail模板
在AX中使用邮件模板可以,可以让邮件的内容更专业化.下面,跟随Reinhard一起,配置E-Mail模板吧. 进入Organization Administration>Setup>E-m ...
- mybatis动态SQL标签的用法
动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格 ...
- JAVA线程同步辅助类CyclicBarrier循环屏障
CyclicBarrier是一个同步辅助类,主要作用是让一组线程互相等待,知道都到达一个公共障点,在一起走.在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrie ...
- WP8没有开发者账号升级GDR3预览版的方法
很多希望尝鲜WP8 GDR3的朋友一样希望提前体验GDR3的效果,但苦于没有开发者账号而不得其门!今天为大家带来普通账号升级GDR3的方法! 工具/原料 WP8智能手机 可用wifi热点 方法/步骤 ...
- SNMP OID列表 监控需要用到的OID
zabbix的snmp监控还没开始讲,不过先给大家列一些snmp常用的一些OID,比如cpu.内存.硬盘什么的.先了解这些,在使用snmp监控服务器. 系统参数(1.3.6.1.2.1.1) OID ...
- IOS开发之异步加载网络图片并缓存本地实现瀑布流(二)
/* * @brief 图片加载通用函数 * @parma imageName 图片名 */ - (void)imageStartLoading:(NSString *)imageName{ NSUR ...