入门:构建简单的Web API
WCF Web API支持多个宿主环境:自宿主(windows服务或者控制台)和IIS宿主(asp.net webform/mvc)。这个入门文章主要演示在ASP.NET MVC3网站宿主:
- 如何使用NuGet向项目中添加Web Api引用
- 如何创建一个通过HTTP GET访问的Web Api
- 如何通过asp.net routes宿主一个Web Api
- 如何通过浏览器或者Fiddler访问Web Api
- 如何在Api上启用OData uri查询
- 如何用WCF Web Test Client测试WCF Web API
1、创建一个基本的解决方案:使用VS2010新建一个空的ASP.NET MVC 3 Web Application
设置站点的端口号为9000
2、向解决方案中加入Web Api的引用
通过NuGet来添加Web api的程序集引用,右击项目属性,选择“Manage NuGet Packages”
在NuGet管理扩展器上查询Online的”webapi.all“
选择安装,NuGet就会下载所有所需的软件包,现在可以开始开发Web Api。
3、创建一个Contacts Api类
右击项目ContactManager选择添加一个文件夹,取名”APIs“,然后在APIs文件夹上右击添加类,类名叫做ContactsApi:
using System.ServiceModel;
namespace ContactManager.APIs
{
[ServiceContract]
public class ContactsApi
{
}
}
ContractsApi 加了ServiceContractAttribute表示这是一个WCF 服务,将通过HTTP方式暴露出来。
4、通过asp.net routing注册ContractsApi
Api需要通过asp.net mvc宿主,使用ASP.net Route的MapServiceRoute扩展方法把它注册进去。切换到global.asax.cs文件,添加以下引用
using ContactManager.APIs;
using System.ServiceModel.Activation;
在RegisterRoutes方法里加入下述代码
routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));
下面的黄色部分很重要,MVC的默认路由是映射到controller + action
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory(), typeof(ContactsApi)));
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
MapServiceRoute需要一个泛型参数指定服务(API),以及一个将被追加到IIS base url的路径。在这里,我们指定的“contacts”,也就是宿主为“http://localhost:9000/api/contacts”。
5. 通过一个HTTP Get 方法暴露contacts:首先创建一个poco(Plain Old C#)Contract类,代表我们在api上传递的联系人,本质上就是一个DTO(数据传输对象),在HTTP上我们把它作为资源,然后创建一个HTTP Get方法暴露资源。
右击项目ContactManager项目选择添加新的文件夹“Resources”,在Resources文件下创建一个新的类Contact。
namespace ContactManager.Resources
{
public class Contact
{
public int ContactId { get; set; }
public string Name { get; set; }
}
}
返回到ContactApi类,添加下述引用:
using System.ServiceModel.Web;
using ContactManager.Resources;
添加一个Get方法返回所有的contracts
[WebGet(UriTemplate = "")]
public IQueryable<Contact> Get()
{
var contacts = new List<Contact>()
{
new Contact {ContactId = 1, Name = "Phil Haack"},
new Contact {ContactId = 2, Name = "HongMei Ge"},
new Contact {ContactId = 3, Name = "Glenn Block"},
new Contact {ContactId = 4, Name = "Howard Dierking"},
new Contact {ContactId = 5, Name = "Jeff Handley"},
new Contact {ContactId = 6, Name = "Yavor Georgiev"}
};
return contacts.AsQueryable();
}
Get方法上加了WebGet Attribute表示这是一个HTTP Get。注意这里的UriTemplate被设置为“”,默认情况下,操作的Uri是方法名Get,在这种情况下,我们是在Route中设置的Uri。
6、通过浏览器查询Contracts.按F5运行项目,然后再浏览器地址栏中输入http://localhost:9000/api/contacts
7、查询返回Json格式的Contracts。HTTP提供了一些“内容协商”机制 — 当有多个可得的表现形式的时候,对特定的响应选择最好的表现形式的处理过程。
服务器驱动协商(Server-driven Negotiation)
如果响应的最好的表现形式的选择是通过服务器上的算法来实现,那么这种方式的协商称做服务器驱动协商。选择是基于响应可得的表现形式(根据不同的维度,响应会不同;例如,语言,内容编码,等等)和请求消息里特定的头域或关于请求的其他信息(如:网络客户端的地址)。 服务器驱动协商是有优点的,当从可行的表现形式里进行选择的算法对用户代理进行描述是比较困难的时候,或者当服务器期望发送“最好的猜测”给客户端而只通过一个响应(以避免后续请求的回路(一个请求会返回一个响应)延迟如果此“最好的猜测“对用户适合的时候)的时候。为了改善服务器的猜测,用户代理应该包含请求头域(Accept,Accept-Language,Accept-Encoding,等等),这些头域能描述它对响应的喜好。
Web api返回的响应很容易添加一种媒体类型(media types )。
打开Fiddler,在“Request builder”栏输入地址“http://localhost:9000/api/contacts”,然后移动到“Request Headers”在“User-Agent” 项下方添加 “Accept: application/json”
按下 Exectue按钮,双击左边的Panel查看HTTP的response,切换到“Raw”Tab,你可以看到下面的json格式的数据:
8、启用OData 查询支持
Web API支持OData协议,接受OData的URI格式查询,当OData 查询到达Web Api, 在返回客户端之前在服务端会进行必要的过滤和排序。查询使用IQueryable 接口,服务端并没有去查询所有的数据,发送过滤和排序到服务端。
return contacts.AsQueryable();
运行程序,在浏览器里输入 http://localhost:9000/api/contacts?$Top=4&$OrderBy=Name ,看到浏览器之返回了按名字排序的top 4个contract
也可以通过Fidder去查询,具体可参照第7步。
9、WCF Web API也提供了一个WCF Web Test Client用于测试WCF Web API,通过配置启用,在RegisterRoutes方法里创建HttpConfiguration 实例,并设置EnableTestClient属性为True:
var config = new HttpConfiguration() { EnableTestClient = true };
然后把HttpConfiguration实例传递给HttpServiceHostFactory的配置属性
routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory() { Configuration = config }, typeof(ContactsApi)));
按下F5 启动调试项目,然后再浏览器后面加入/Test
总结
通过这个Quick start,我们学习到了以下内容
- 如何使用NuGet向项目中添加Web Api引用
- 如何创建一个通过HTTP GET访问的Web Api
- 如何通过asp.net routes宿主一个Web Api
- 如何通过浏览器或者Fiddler访问Web Api
- 如何在Api上启用OData uri查询
- 如何用WCF Web Test Client测试WCF Web API
你可以在这里获取到代码。
2011-10-4日更新到WebAPI 0.5 Preview
- Tensorflow动态seq2seq使用总结
- 卷积神经网络中PET/CT图像的纹理特征提取
- 深入剖析Spring(四)——AOP
- Java并发编程的艺术(十二)——线程安全
- 用 LSTM 做时间序列预测的一个小例子
- Java并发编程的艺术(十一)——线程池(2)
- Java并发编程的艺术(十)——线程池(1)
- Tensorflow on Spark爬坑指南
- Boost asio 官方教程
- 0基础教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)
- 柴毛毛大话设计模式——开发常用的设计模式梳理
- Redis源码分析(四)——Redis数据结构-整数集合
- Redis源码分析(三)——Redis数据结构-字典
- Redis源码分析(二)——Redis数据结构-链表
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android:流式布局实现总结
- 跨域问题汇总
- 优化 Docker 镜像大小常见方法
- 第10期:选择合适的表空间
- 在 Kubernetes 上编排 MongoDB 集群
- k8s技术圈一周精选[第7期]
- TypeScript namespace 命名空间
- 从Pytorch 的ONNX到OpenVINO中IR中间层
- Linux CPU 性能优化指南
- 差分隐私(Differential Privacy)
- ubuntu changelog/source获取方法
- element ui 图片上传封装多张或单张
- Android:友盟分享升级问题总结
- vue+element实现分页的封装
- 一款基于 Python 语言的 Linux 资源监视器!