(转)Web API 强势入门指南
原文地址: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 集成 MongoDB
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。

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。

public interface IContactRepository {
IEnumerable<Contact> GetAllContacts();
Contact GetContact(string id);
Contact AddContact(Contact item);
bool RemoveContact(string id);
bool UpdateContact(string id, Contact item);
}

ContactRepository的完整实现如下,

public class ContactRepository : IContactRepository
{
MongoServer _server = null;
MongoDatabase _database = null;
MongoCollection<Contact> _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<Contact>("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<Contact> 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命名的。

public class ContactsController : ApiController
{
private static readonly IContactRepository _contacts = new ContactRepository(string.Empty); public IQueryable<Contact> 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。

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,以及通过动态绑定将数据呈现在网页上。

@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页面的链接如下
<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特指ASP.NET Web API. 这篇文章中我们主要介绍Web API的主要功能以及与其他同类型框架的对比,最后通过一些相对复杂的实例 ...
- Web API学习——Web API 强势入门指南
Web API是一个比较宽泛的概念.这里我们提到Web API特指ASP.NET Web API. 这篇文章中我们主要介绍Web API的主要功能以及与其他同类型框架的对比,最后通过一些相对复杂的实例 ...
- Asp.Net Web API 2(入门)第一课
Asp.Net Web API 2(入门)第一课 前言 Http不仅仅服务于Web Pages.它也是一个创建展示服务和数据的API的强大平台.Http是简单的.灵活的.无处不在的.你能想象到几乎 ...
- 水果项目第3集-asp.net web api开发入门
app后台开发,可以用asp.net webservice技术. 也有一种重量级一点的叫WCF,也可以用来做app后台开发. 现在可以用asp.net web api来开发app后台. Asp.net ...
- Web API 2 入门——使用Web API与ASP.NET Web窗体(谷歌翻译)
在这篇文章中 概观 创建Web窗体项目 创建模型和控制器 添加路由信息 添加客户端AJAX 作者:Mike Wasson 虽然ASP.NET Web API与ASP.NET MVC打包在一起,但很容易 ...
- Web API 2 入门——Web API 2(C#)入门(谷歌翻译)
ASP.NET Web API 2(C#)入门 在这篇文章中 本教程中使用的软件版本 创建一个Web API项目 添加模型 添加控制器 使用Javascript和jQuery调用Web API 运行应 ...
- ASP.NET Core Web API 最佳实践指南
原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 介绍 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但是,你难 ...
- [转]ASP.NET Core Web API 最佳实践指南
原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 转自 介绍# 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但 ...
- 1.1ASP.NET Web API 2入门
HTTP 不只是为了生成 web 页面.它也是建立公开服务和数据的 Api 的强大平台.HTTP 是简单的. 灵活的和无处不在.你能想到的几乎任何平台有 HTTP 库,因此,HTTP 服务可以达到范围 ...
随机推荐
- python 函数 hex()
hex(x)作用:hex() 函数用于将10进制整数转换成16进制整数. x-10进制整数,返回16进制整数 实例: >>>hex(255) '0xff' >>> ...
- 第2章 深入分析java I/O的工作机制(上)
java的I/O操作类在包java.io下,大致分成4组: 所有文件的存储都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再存储这些字节到磁盘.在读取文件时,也是一个 ...
- C++面试题(三)
1 什么是函数对象?有什么作用? 函数对象却具有许多函数指针不具有的有点,函数对象使程序设计更加灵活,而且能够实现函数的内联(inline)调用,使整个程序实现性能加速. 函数对象:这里已经说明了这是 ...
- Py修行路 python基础 (十六)面向对象编程的 继承 多态与多态性 封装
一.继承顺序: 多继承情况下,有两种方式:深度优先和广度优先 1.py3/py2 新式类的继承:在查找属性时遵循:广度优先 继承顺序是多条分支,按照从左往右的顺序,进行一步一步查找,一个分支走完会走另 ...
- a标签什么时候可以设置宽高
行内元素(如a标签),在文档流中的时候因为是行内元素所以无法设置宽高:而当设置了绝对定位或者浮动,会生成块框(即变成块元素),所以就可以设置宽高了
- Aptana Studio 3 如何汉化,实现简体中文版
这篇文章写了又一年多的时间了,哈哈,今天更新一次 此处修正的下面教程的[第五步]Babel Language Pack Update Site for Helioshttp://download.ec ...
- 利用HADOOP中的jar写一个RPC
RPC调用需要服务端和客户端使用相同的协议: 协议: package cn.itcast.bigdata.hadooprpc.protocol; public interface IUserLogin ...
- Hadoop Serialization -- hadoop序列化详解 (2)
回顾: 回顾序列化,其实原书的结构很清晰,我截图给出书中的章节结构: 序列化最主要的,最底层的是实现writable接口,wiritable规定读和写的游戏规则 (void write(DataOut ...
- 25-从零玩转JavaWeb-抽象类
一.抽象类解决什么问题 求三角形,圆,矩形的面积 发现三个类都有共同的方法 ,所以我们可以抽出一个父类, 把他们相同的方法放到父类当中 二.什么是抽象方法 三.什么是抽象类 四.抽象类的特 ...
- Oracle字符集的查看查询和Oracle字符集的设置修改(转)
最近郁闷的字符集2014年7月31日16:32:58 本文主要讨论以下几个部分:如何查看查询oracle字符集. 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题 ...