这篇文章只是我学习Web API框架的输出,学习方法还是输出倒逼输入比较行得通,所以不管写的好不好,坚持下去,肯定有收获。篇幅比较长,仔细思考阅读下来大约需要几分钟。

做.NET开发有好几年时间了,从很久之前的WebFormMVC,再到目前前后端分离模式下RESTful风格的 Web API ,相信这些Web框架很多人都或多或少的用过,也算见证了NET Web端的某一阶段的发展吧,同时很多技术随着发展和迭代,以及前后端分离模式的普及和兴起,用的机会少了,难免可能觉得已经过时了,同时现在流行的Web框架太多太多,不局限于.Net,同样也很优秀,例如:

Java的Spring | Hibernate

Python的Django | Flask

Node的Express和Koa

其实最重要的不是用了多少,知道多少,而是有多少沉淀,在使用领域虽然可能存在过时了,但是从技术的角度,框架设计的思想代码风格技术点的使用把控甚至变量声明等等,都值得我们去学习。

分享方式

  1. Web API 路由注册路由处理通过阅读源代码以及边说明的的方式来阐述。
  2. Web API 管道组装和扩展虽然我们在阅读源码时会接触到它,但我仍然会用Demo的方式来说明它.
  3. Web API 管道组装和扩展我觉得它设计的真的很棒,忍不住要单独拎出来说一下,虽然有可能把自己讲懵,但我仍然想尝试一下。

1. Web API 路由简介
1.基本介绍

一个ASP.NET的Web应用具有一个全局的路由表,它是通过一个RouteTable类中的一个类型为RouteCollectionRoutes静态属性来表示的。

为什么这么说呢?或许这样说不太好理解,用一个简单的例子来说明,我们修改Api框架启动时,注册路由的方式,改为直接用 RouteTable.Routes来添加,这种做法跟框架提供的是一样的,最终都是将路由添加到一个地方。

在针对于路由表这一点上面不仅仅只有WebAPI是这么做的,他同样适用于WebFormMVC 同样可以直接在应用程序启动时网路由表中直接添加数据,不过此处只为了证实上述描述,在日常开发中是否可以这样用,完全取决于你自己。

1.框架提供的

public static void Register(HttpConfiguration config)
{
// Web API 框架提供的路由
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{Action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}

2.通过直接路由表添加

 //在WebApiConfig.Register中修改注册路由.
public static void Register(HttpConfiguration config)
{
//验证路由是否加到全局路由表
var ro = new { id = RouteParameter.Optional };
//获取默认WebAPI路由处理器
IRouteHandler routeHandler = HttpControllerRouteHandler.Instance;
RouteValueDictionary defaults = new RouteValueDictionary(ro);
Route route = new Route("api/{controller}/{Action}/{id}", defaults, routeHandler);
RouteTable.Routes.Add("DefaultApi", route);
}
2.思考的问题

1.我们思考RouteCollection为什么是静态的?

因为静态对象会一直存在内存中,直到程序池下一次回收之前.`

2.我们在用WebAPI开发应用接口的时候,前端Url请求是怎么通过路由到达我们对应的控制器和Action的?

其实是根据路由来控制的,至于怎么控制,怎么实现,后面会慢慢介绍.

3.路由控制如何路由呢?

1.先注册路由,再将路由和处理器绑定。

2.然后用户请求根据请求的Url 匹配对应的处理器,再由处理器进行路由模板规则解析。

3.根据解析到的规则反射找到Contrller和Action。

2. Web API 路由注册

路由注册这一部分在MVC5之后就有2部分了,新增了一个特性路由,此次不做分享,后续有机会再补上..我们看下简单的路由注册图,当然其中还有很多东西,只是画的比较简陋,

上面的所表示的流程中,我们作为使用框架的开发人员,关注的只是其中一小部分,从代码角度能看到,就只有如下很简单的几句代码,并且连这个代码都是框架生成的,从另一个角度也说明框架的封装比较完整和强大,让开发人员只关注自己的业务就行了

注册路由流程部分

1.注册方式

1.在Web Api程序启动时,首先调用GlobalConfiguration.Configure(WebApiConfig.Register)方法,这个方法接收的参数是一个Action<HttpConfiguration> 作为参数,看到Action我们的第一反应就是作为回调执行, 框架给我们预留了扩展空间,用户扩展的内容在内部执行

2.说白了GlobalConfiguration.Configure()方法的参数,需要一个委托,而委托的本质就是一个无返回值,包含HttpConfiguration类型的实例作为参数的方法,我们转到框架定义的WebApiConfig.Register()方法,毫无疑问它符合要求,所以这个方法就是在框架中被GlobalConfiguration.Configure() 执行的回调,而这个回调的作用就是注册路由

注册路由作为框架GlobalConfiguration.Configure的回调,与上图中相等

2.GlobalConfiguration

我们发现更多的信息在GlobalConfiguration类中,继续一步步解读,打开源码找到GlobalConfiguration这个类来看

1.它是个静态类包含一个重要的方法Configure(Action configurationCallback)

2.它包含3个重要的静态属性ConfigurationDefaultHandlerDefaultServer

3.三个属性被调用时就已经初始化了,但被Lazy类型包裹,说明是被延迟执行,具体延迟执行的时机就是调用它的Value属性时。

4.目前在路由注册阶段只介绍Configuration,剩下2个在路由解析部分在分享.

1.我们首先看GlobalConfiguration.Configure(Action configurationCallback) 的内部做了2件事,执行我们扩展的回调,也就是注册路由的业务,然后检查初始化HttpConfiguration

执行回调需要的参数,正是第一个属性Configuration 通过该类型的Routes属性的MapHttpRoute扩展方法来往路由表中添加数据。可以知道我们只要搞清楚了HttpConfiguration类型的Configuration的来源,就能搞清楚很多事情。

我们找到HttpConfiguration类型的Configuration是怎么初始化的,先展开它,查看代码看到他是由内部的CreateConfiguration()方法创建的

3.注册流程步骤

1.在CreateConfiguration()HttpConfiguration被构造时我们经过查看上下文发现

1.传入一个HostedHttpRouteCollection对象,并在内部赋值给HttpRouteCollection类型的_routes属性

2.HostedHttpRouteCollection在构造时,传入了我们的全局路由表RouteTable.Routes

2.我们找到映射路由的扩展方法MapHttpRoute可以知道我们调用它的Route属性是一个HostedHttpRouteCollection也就是说,在MapHttpRouteCreateRoute()是由HostedHttpRouteCollection来调用的

3.继续转到HostedHttpRouteCollection类中的CreateRoute()内部看到它返回一个HostedHttpRoute而它就是实现IHttpRoute的实例。

4.继续深入在HostedHttpRoute构造时,内部有一个Route类型的OriginalRoute属性,它被赋值为继承自(Route:RouteBase)HttpWebRoute类型。

5.在HttpWebRoute初始构造时传入了几个极为重要的参数路由模板IRouteHandler类型HttpControllerRouteHandler以及一个IHttpRoute类型的HostedHttpRoute,然后程序返回,注意此处的IRouteHandler可以理解为是路由的处理器.最终在HostedHttpRouteCollection对象上调用routes.Add(name, route)添加 路由模板名字处理程序.

4.总结

现在我们对Web Api中的路由注册部分已经做了一个简单的介绍,并且一步一步理解了源码实现的逻辑,其实说到本质,路由注册只做了一件事,就是将路由模板规则和路由处理器提前绑定,客户端按照对应的规则请求来匹配对应的路由处理器做最终的处理,而目前框架内置的路由处理器就是一个HttpControllerRouteHandler,后面部分进入路由处理,如果在阅读过程中有任何疑问欢迎随时和我讨论, 强烈建议在阅读本篇分享建立了粗略的知识点之后,有时间的话自己先下载Web Api源码进行阅读,这样可以帮助更好的理解。

Web Api源码(路由注册)的更多相关文章

  1. Web API 源码剖析之默认消息处理程序链之路由分发器(HttpRoutingDispatcher)

    Web API 源码剖析之默认消息处理程序链-->路由分发器(HttpRoutingDispatcher) 我们在上一节讲述了默认的DefaultServer(是一个类型为HttpServer的 ...

  2. Web API 源码剖析之默认消息处理程序链--》路由分发器(HttpRoutingDispatcher)

    我们在上一节讲述了默认的DefaultServer(是一个类型为HttpServer的只读属性,详情请参考 Web API 源码剖析之全局配置).本节将讲述DefaultHandler(是一个Http ...

  3. Web API源码剖析之HttpServer

    Web API源码剖析之HttpServer 上一节我们讲述全局配置.本节将讲述全局配置的DefaultServer,它是一个HttpServer类型. 主要作用就是接受每一次请求,然后分发给消息处理 ...

  4. Web API 源码剖析之全局配置

    Web API 源码剖析之全局配置 Web API  均指Asp.net Web API .本节讲述的是基于Web API 系统在寄宿于IIS. 本节主要讲述Web API全局配置.它是如何优雅的实现 ...

  5. Web API 源码剖析之默认配置(HttpConfiguration)

    Web API 源码剖析之默认配置(HttpConfiguration) 我们在上一节讲述了全局配置和初始化.本节我们将就全局配置的Configuration只读属性进行展开,她是一个类型为HttpC ...

  6. Dubbo源码学习--注册中心分析

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 注册中心 关于注册中心,Dubbo提供了多个实现方式,有比较成熟的使用zookeeper 和 redis 的 ...

  7. Web API框架学习——路由(一)

    HttpConfiguration(ASP.NET Web API管道的配置是通过HttpConfiguration来完成) : 包括路由注册在内的对整个ASP.NET Web API管道的配置是通过 ...

  8. Android 如何在Eclipse中查看Android API源码 及 support包源码

    当我们阅读android API开发文档时候,上面的每个类,以及类的各个方法都是已经写好的方法和控件,可是我们只是在搬来使用,不知道它的原理,它是如何被实现的.android系统是开源的,所以谷歌官方 ...

  9. 【转】Android 如何在Eclipse中查看Android API源码 及 support包源码

    原文网址:http://blog.csdn.net/vipzjyno1/article/details/22954775 当我们阅读android API开发文档时候,上面的每个类,以及类的各个方法都 ...

随机推荐

  1. 学习Solr(一)

    一.安装 1.需要的安装包:apache-tomcat-7.0.47.tar.gz.solr-4.10.3.tgz.tgz(jdk自行安装) 2.解压tomcat并创建solr文件夹 [root@lo ...

  2. 机器学习之近邻算法模型(KNN)

    1..导引 如何进行电影分类 众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪 个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问 ...

  3. STM32 中的 assert_param 函数

    在学STM32的时候函数assert_param出现的几率非常大,上网搜索一下,网上一般解释断言机制,做为程序开发调试阶段时使用. 断言机制函数assert_param我们在分析库函数的时候,几乎每一 ...

  4. Linux基础学习 | 用户及用户组

    Linux 用户及用户组 目录 一.用户    添加用户实例 二.用户组    添加用户组实例 三.用户及用户组文件 四.各命令参数对照 一.用户 Linux系统是一个多用户多任务的分时操作系统.任何 ...

  5. IPython是什么?

    参考:IPython 中常用的魔法命令 Ipython中的魔法命令总结 IPython 是一个 python 的交互式 shell,比默认的python shell 好用得多,支持变量自动补全,自动缩 ...

  6. 用 JWT 实现小程序本地用户标识

    panda-chat-room 继上节「理解小程序 session」 ,本节我们以 jsonwebtoken 来实现小程序端的用户状态标识.如果你对小程序用户登录流程及 session 管理还有些疑惑 ...

  7. 正则系列——JavaScript正则表达式入门心得

    我发现有个别字符被这个编辑器给刷掉了,但是灰色区域显示正常,以灰色区域代码为准 什么玩意? 在我刚开始学习编程的时候,就听过正则了,也听说正则很牛逼,懂正则的更牛逼.但是苦于没有人指点,也没有使用正则 ...

  8. CentOS 7.9 网络配置

    vi /etc/sysconfig/network-scripts/ifcfg-ens33 (45条消息) CentOS 7.9 网络配置_$青的博客-CSDN博客_centos7.9网卡配置

  9. 自定义API(Jar包)的创建与使用(简单实现案例)

    @ 目录 学习内容 1. 自定义工具类 2. 导出jar 3. 加载Jar包 4. 调用自定义的API方法 总结 学习内容 1. 自定义工具类 新建一个java项目,然后创建包和工具类StringUt ...

  10. 数组-LeetCode-笔试

    目录 数组理论基础 二分查找 二分法第一种写法 二分法第二种写法 ACM 移除元素 暴力解法 双指针法(快慢指针) ACM 有序数组的平方 暴力排序 双指针法 长度最小的子数组 暴力解法 滑动窗口 相 ...