我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西。对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠。如果我们将整个“生态系统”比喻成海面上漂浮的冰山,我们所能看的到的只是露出水面的冰山一角,水面之下才是一个“庞然大物”。
提到服务,我们自然想到Web Service。但是传统意义上的Web Service却有点名不副实,因为支撑它的其实不是Web而是SOAP,承载一个Web Service甚至可以根本不需要Web。随着互联网的普及,互联网应用(尤其移动互联网应用)已经成为主流,“SOAP之重”已经越来越令我们无法承受,于是采用REST架构风格并直接采用Web进行通信的轻量级Web Service走进了我们的视野并登堂入室。为了与传统的基于SOAP的Web Service以示区别,我们将后者称为Web API。
很多人鼓吹SOAP已死,我个人对此持不同的看法。上面讲的“重”与“轻”都是不带任何感情色彩的中性词,至于优劣评价则决定于它们是否适合应用的场景。到目前为止,对于企业级应用之间的内部集成互联,我觉得传统的Web Service依然是最好的选择。传统Web Service应用的领域貌似在不断被Web API占据,但是后者并不能完全被视为前者的替代品,它只是让“踩过界”的Web Service退回到它应该坚守的领地。Web Service和Web API在各自适合的领域各司其职,使“路归路、桥归桥”是一种理想的状态。
Web Service和Web API的合理布局同样也体现在微软技术平台上。WCF在过去是唯一的选择,这是一个具有“SOAP”基因的通信平台,微软后来利用扩展让它提供了针对REST的支持。正因为如此,如果使用WCF来构建Web API的话,我们依然需要采用传统的编程方式,Web API的“简单、快捷”完全得不到体现。微软意识到在一个“重量级”通信框架上通过扩展实现“轻量级”的通信,还不如重新构建一个通信平台,于是ASP.NET Web API应运而生。
这不是一本传统意义上的入门书籍
任何一本书都具有对应的受众群体,所以我不得不将这句话放在最前面,并且希望所有打算购买此书的读者能够看到。如果你之前对ASP.NET Web API(或者ASP.NET MVC)完全没有概念,在某一天突然被安排去开发一个需要使用到ASP.NET Web API的项目,你希望有那么一本书能够在一个星期或者更短的时间内帮助你掌握ASP.NET Web API基本的编程方式,那么这本书不适合你。
我个人很喜欢金庸和古龙的武侠小说,我觉得学习某种开发框架就像是练一门武功。一门武功具有“招式“和”心法“之分,外在的招式可以速成,而内功心法绝非一蹴而就,但是没有内功心法支撑的招式只是花拳绣腿。对于某种开发框架来说,基本的编程模式就是招式,框架本身的设计就是心法。
“训练招式”和“传授心法”的书我们都需要,并且不能根据这点来评判一本书的优劣。就本书而言,这是一本苦练内功心法的书。对于大部分读者来说,我觉得在很短的时间内完全掌握本书的内容并不是一件容易的事情,所以如果你没有决定花较多的时间和精力阅读此书的话,我还是建议你选择其他相关的书籍。
我在《ASP.NET MVC 4框架揭秘》一书中写过这么一段话:“掌握ASP.NET MVC具有三个层次,了解基本的编程模式为第一层次,能够清晰认识ASP.NET MVC框架本身从请求接收到响应回复的整个流程为第二层次,最高的层次则是能够灵活*地利用ASP.NET MVC提供的扩展点解决开发过程的实际问题”。这句话同样适用于针对ASP.NET Web API的学习,本书写作的目的是使第一层次的读者快速进入第二层次和第三层次。
这是一本实用的书吗?
可能有人觉得这本讲述ASP.NET Web API架构设计和剖析框架运行原理的书没有什么“实际”的意义,因为我们每天的日常工作就是编程,知道了ASP.NET Web API从请求接收到响应回复之间的整个处理流程并不会对实际工作产生实质性的改变。其实这种想法是极端错误的,因为我们编写的程序最终是在框架上运行的,程序的高效性决定于它是否能够最大限度地“迎合”框架的运行机制,所以了解ASP.NET Web API框架的运行原理有利于我们写出高质量的程序。
常年以来,我个人的主要工作就是维护和设计公司内部的一个开发框架。这是一个在集团内部广泛采用的针对.NET的开发框架,它的存在使流水线式的软件开发成为可能,这个框架不仅仅提高了生产效率和产品质量,还降低了对最终开发人员技能的要求。之所以能够做到这一点,原因在于几乎所有与业务无关的功能(比如日志、异常处理、权限控制、安全审核、事务处理等)都由这个框架来完成,最终的开发人员只需要实现具体的业务逻辑就可以了。
对于这个开发框架来说,针对相应开发技术所做的扩展和工具是一个重要的组成部分,所以出于本职工作的需要,我不得不对采用的主流开发技术进行深入研究,因为只有在对其内部运行原理了然于胸的情况下才能精准地找到一个最适合的扩展点来解决具体项目开发过程中遇到的问题。很多读者都问过我同样一个问题:“为什么你能够了解那么多关于WCF、ASP.NET MVC和ASP.NET Web API这些技术的内部细节”,我先告诉你们答案:因为这是我本职工作的一部分。为了将这些实用的研究成果服务于更多的人,我将它们写到我的多本书中。
可以将本书当成一本讲述设计架构的书来读
在我的周围存在着这样一些人,这些人以刚毕业一两年的大学生为主,他们大都工作勤奋、聪明好学,手中经常捧着GoF的《设计模式》,总是希望将书中的设计模式应用到具体项目之中,或者希望通过项目的实践来印证他们在书本上学到的设计模式,但是理论和实践之间的距离总让他们感到困惑。
要从真实的项目或者产品中学习“实用”的软件架构设计知识,先得确定目标项目或者产品中采用的架构思想和设计模式是正确的,而我们参与的很多项目其实被“架构”得一塌糊涂。对于像ASP.NET这样的产品,其基础架构能够在很长一段时间内保持不变,本身就证明了应用在上面的架构设计的正确性,它们不正是我们学习架构设计最好的素材吗?
就我个人而言,很多设计架构方面的知识都是近年来深入研究WCF、ASP.NET MVC、ASP.NET Web API、Enterprise Library和Unity这些开发技术和开源框架的过程中获取的。对于那些只会拿猫、狗这些东西举例的设计模式的书籍来说,这些东西是学不到的。本书除了介绍一些技术细节之外,实际上还将ASP.NET Web API的整个架构设计展现在读者面前,相信有心的读者会从中学到不少关于架构设计方面的知识。
如果你手头刚好有一本《ASP.NET MVC 4框架揭秘》(《ASP.NET MVC 5框架揭秘》也即将出版),可以将这两本书对照着一起看。对于相同的功能点,认真思考一下为何它们在ASP.NET MVC和ASP.NET Web API中会采用不同的设计,两种设计孰优孰劣,我想收获会更大。
本书承载了个人针对新技术的学习方法
在过去几年中,有些热心的读者和网友都向我咨询过一个问题:“对于一门新的技术,如何能够在短时间内掌握其精髓”。这是一个学习方法的问题,虽然我觉得每个人都有适合自己的学习方法,但我还是刻意地将我个人采用的方式体现在本书之中,希望它对某些读者有用。如果读者是个有心人,应该可以看到我在介绍某个知识点的时候,不仅仅会告诉你“是什么”和“为什么”,还会告诉你“如何证明是这样”。换句话说,我不仅仅将某个论点抛给你,还为你展现了整个论证的过程,实际上我在学习过程中就是这么做的。
本书的写作特点
本书具有一个与其他中文原创或者翻译书籍截然不同的特点,那就是几乎所有的术语都采用英文,比如HttpController、Action和Model在本书中并没有翻译成中文“HTTP控制器”、“操作”和“模型”。因为我认为很多术语其实很难找到一个语义完全等同的中文词组或短语与之对应,对于习惯了英文作为“开发语言”的读者来说,强行翻译其实是不必要的。
除此之外,这不是一本纯理论的书,而是一本“实证型”的书,在书中提供了120个可供单独下载的实例演示。这些实例在本书中具有不同的作用,有的是为了探测和证明对应的论点,有的是为了演示使用的某种编程技巧。
本书读者
虽然这不是一本传统意义上的入门书籍,但是我不会根据读者的技能将某一部分人排除在本书的读者之外。与市面上绝大部分同类书籍相比,我宁愿说这本书走得更远而不是钻得更深,因为虽然本书更加近距离地触及了ASP.NET Web API框架内核,但是涉及的内容本身并没有什么高深莫测之处,对于具有基本.NET基础的读者应该都看得懂。所以我觉得本书适合那些对深层次了解ASP.NET Web API的开发人员和架构师,不论读者处于怎样的层次总会找到相应的“盲点”。
目录
第1章 概述
1.1. 何为Web?
1.1.1. TCP/IP与HTTP
1.1.2. Web资源
1.1.3. HTTP事务
1.1.4. HTTP报文
1.2. RESTful Web API
1.2.1. 为什么叫这个“奇怪”的名字?
1.2.2. RESTful Web API具有怎样的特征
1.3. 初识ASP.NET Web API
1.3.1. 构建解决方案
1.3.2. 定义Web API
1.3.3. 以Web Host方式寄宿Web API
1.3.4. 以Self Host方式寄宿Web API
1.3.5. 利用HttpClient调用Web API
1.3.6. 创建一个“联系人管理器”应用
第2章 路由
2.1. ASP.NET路由
2.1.1. 请求URL与物理文件的分离
2.1.2. 实例演示:通过URL路由实现请求地址与Web页面的映射(S201)
2.1.3. ASP.NET路由系统
2.1.4. 注册路由映射
2.1.5. 根据路由规则生成URL
2.1.6. HttpHandler的动态映射
2.2. ASP.NET Web API路由
2.2.1. 请求与响应
2.2.2. ASP.NET Web API路由系统
2.2.3. 注册路由映射
2.3. 两个路由系统的衔接
2.3.1. HostedHttpRoute与HostedHttpRouteCollection
2.3.2. HttpControllerRouteHandler与HttpControllerHandler
第3章 消息处理管道
3.1. HttpMessageHandler管道
3.1.1. HttpMessageHandler
3.1.2. DelegatingHandler
3.1.3. HttpServer
3.1.4. HttpRoutingDispatcher
3.2. Web Host模式下的消息处理管道
3.2.1. HttpControllerHandler
3.2.2. 实例演示:自定义HttpMessageHandler实现HTTP方法重写(S305)
3.3. Self Host下的消息处理管道
3.3.1. HttpBinding
3.3.2. HttpSelfHostServer
第4章 HttpController的激活
4.1. HttpController
4.1.1. HttpControllerContext
4.1.2. HttpControllerDescriptor
4.1.3. ApiController
4.2. HttpController是如何被创建的
4.2.1. 程序集的解析
4.2.2. HttpController类型的解析
4.2.3. HttpController的选择
4.2.4. HttpController的创建
4.2.5. HttpController的激活与释放
4.3. IoC的应用
4.3.1. 利用Unity来认识IoC
4.3.2. 基于IoC的HttpControllerActivator
4.3.3. 基于IoC的DependencyResolver
第5章 Action的选择
5.1. HttpActionDescriptor
5.1.1. ReflectedHttpActionDescriptor
5.1.2. ActionNameAttribute
5.1.3. 方法名决定HTTP方法
5.1.4. ActionHttpMethodProvider
5.1.5. 针对特性的缓存
5.2. HttpParameterDescriptor
5.2.1. ReflectedHttpParameterDescriptor
5.2.2. 实例演示:解析Action方法参数描述信息(S503)
5.3. HttpActionSelector
5.3.1. ApiControllerActionSelector
5.3.2. 有效的Action方法
5.3.3. 目标Action方法的选择
第6章 特性路由
6.1. 特性路由注册
6.1.1. HttpRouteInfoProvider特性
6.1.2. 基本路由映射
6.1.3. 让URL模板能够尽可能反映资源的层次结构
6.1.4. 为路由变量设置约束
6.1.5. 通配符路由变量
6.1.6. 缺省路由变量
6.1.7. 设置URI前缀
6.2. 约束表达式的解析
6.2.1. RangeRouteConstraint
6.2.2. InlineConstraintResolver
6.2.3. 自定义约束
6.3. 路由解析
6.3.1. RouteCollectionRoute
6.3.2. 实例演示:查看特性路由注册生成的RouteCollectionRoute对象(S609、S610、S611)
6.3.3. 子路由对象的创建
6.3.4. HttpRouteData的生成
第7章 Model绑定(上篇)
7.1. Model绑定解决怎样的问题?
7.1.1. 基于HttpRouteData的参数绑定
7.1.2. 基于查询字符串的参数绑定
7.2. Model元数据的解析
7.2.1. Model元数据的层次化结构
7.2.2. ModelMetadata
7.2.3. ModelMetadataProvider
7.3. ValueProvider
7.3.1. ValueProviderResult
7.3.2. NameValuePairsValueProvider
7.3.3. RouteDataValueProvider与QueryStringValueProvider
7.3.4. CompositeValueProvider
7.4. ValueProviderFactory
7.4.1. RouteDataValueProviderFactory与QueryStringValueProviderFactory
7.4.2. CompositeValueProviderFactory
7.4.3. ValueProviderFactory的注册
7.4.4. 自定义ValueProviderFactory
第8章 Model绑定(下篇)
8.1 ModelBinder
8.1.1. ModelBindingContext
8.1.2. 去除前缀后的二次绑定
8.1.3. CompositeModelBinder
8.2. ModelBinderProvider
8.2.1. CompositeModelBinderProvider
8.2.2. ModelBinderAttribute
8.2.3. Model绑定的流程
8.3. 针对不同目标类型的Model绑定
8.3.1. 简单类型
8.3.2. 复杂类型
8.3.3. 集合
8.3.4. 数组
8.3.5. 字典
8.3.6. 最后一个ModelBinder
8.4. ModelState
8.4.1. ApiController的ModelState
8.4.2. 实例演示:获取Model绑定过程中由ValueProvider提供的数据(S808)
第9章 参数的绑定
9.1. 参数绑定系统全景展示
9.1.1. HttpParameterBinding
9.1.2. ActionValueBinder
9.2. 五个原生的HttpParameterBinding
9.2.1. ModelBinderParameterBinding
9.2.2. FormatterParameterBinding
9.2.3. HttpRequestParameterBinding
9.2.4. CancellationTokenParameterBinding
9.2.5. ErrorParameterBinding
9.3. HttpParameterBinding的创建策略
9.3.1. ParameterBindingAttribute特性
9.3.2. 注册参数绑定规则
9.3.3. HttpParameterBinding的创建策略
第10章 参数的验证
10.1. 几种参数验证方式
10.1.1. 手工验证绑定的参数
10.1.2. 使用ValidationAttribute特性
10.1.3. 创建自我验证数据类型
10.2. 以ModelValidator为核心的参数验证系统
10.2.1. DataAnnotationsModelValidator
10.2.2. RequiredMemberModelValidator
10.2.3. ValidatableObjectAdapter
10.2.4. ErrorModelValidator
10.3. 基于数据注解特性的参数验证
10.3.1. ValidationAttribute特性
10.3.2. DataAnnotationsModelValidator
10.3.3. DataAnnotationsModelValidatorProvider
10.4. 参数验证流程
10.4.1. ModelValidationNode
10.4.2. “验证树”是如何被建立起来的?
10.4.3. “必需”数据成员的验证
10.4.4. BodyModelValidator
第11章 Action的执行
11.1. Action方法的执行
11.1.1. HttpActionInvoker
11.1.2. ActionExecutor
11.2. 内容协商
11.2.1. ContentNegotiator
11.2.2. MediaTypeFormatter是如何被筛选出来的?
11.2.3. 如何确定响应字符集?
11.3. HttpActionResult
11.3.1. 无响应主体HttpActionResult
11.3.2. 含响应主体HttpActionResult
11.3.3. ResponseMessageResult
11.4. HttpResponseMessage的生成
11.4.1. ActionResultConverter
11.4.2. 从消息处理管道来看HttpResponseMessage的生成
第12章 过滤器
12.1. Filter及其提供机制
12.1.1. Filter
12.1.2. FilterProvider
12.1.3. 5种Filter类型
12.2. 认证与授权
12.2.1. Identity
12.2.2. Principal
12.2.3. AuthenticationFilter
12.2.4. AuthorizationFilter
12.3. 针对Action方法执行前后的拦截
12.3.1. ActionFilterAttribute
12.3.2. 实例演示:利用自定义ActionFilter实现对Action方法执行结果的缓存(S1207)
12.4. 异常处理与Filter的屏蔽
12.4.1. ExceptionFilter
12.4.2. 实例演示:利用自定义的ExceptionFilter集成EntLib进行异常处理(S1208)
12.4.3. OverrideFilter
第13章 安全
13.1. IIS/ASP.NET认证
13.1.1. Basic认证
13.1.2. Digest认证
13.1.3. 集成Windows认证
13.1.4. Forms认证
13.2. SSL/TLS
13.2.1. 非对称加密
13.2.2. 通过SSL/TLS实现传输安全
13.2.3. SSL/TLS的应用
13.3. 第三方认证
13.3.1. OAuth 2.0简介
13.3.2. “Implicit” Authorization Grant
13.3.3. “Authorization Code” Authorization Grant
第14章 跨域资源共享
14.1. 同源策略
14.1.1. 实例演示:跨域调用Web API(S1401)
14.1.2. JSONP
14.2. CORS规范
14.2.1. 资源的授权
14.2.2. 实例演示:利用自定义的MessageHandler支持跨域资源共享(S1404、S1405)
14.3. CORS在ASP.NET Web API中的实现
14.3.1. 实例演示:采用ASP.NET Web API原生的机制实现跨域资源共享(S1406)
14.3.2. CORS授权策略及其提供机制
14.3.3. 资源授权的检验和CORS响应报头的生成
14.3.4. CorsMessageHandler
第15章 Web API的调用
15.1. HttpClient
15.1.1. HttpMessageInvoker
15.1.2. HttpClientHandler
15.1.3. HttpClient
15.2. 客户端消息处理管道
15.2.1. HttpMessageHandler管道
15.2.2. HttpClientFactory
15.3. 面向“对象”编程
15.3.1. 将数据对象写入请求消息
15.3.2. 读取HTTP消息主体内容并反序列化为数据对象