1.Global.asax中路由的注册

public class WebApiApplication : System.Web.HttpApplication
{ protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
        //api路由注册
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
} }

2.GlobalConfiguration源码

public static void Configure(Action<HttpConfiguration> configurationCallback)
{
if (configurationCallback == null)
{
throw new ArgumentNullException("configurationCallback");
}
        //执行WebApiConfig.Register方法并传入参数GlobalConfiguration.Configuration
configurationCallback(GlobalConfiguration.Configuration);
GlobalConfiguration.Configuration.EnsureInitialized();
}

(1)参数GlobalConfiguration.Configuration

.public static HttpConfiguration Configuration
{
get
{
return GlobalConfiguration._configuration.Value;
}
}
.private static Lazy<HttpConfiguration> _configuration = GlobalConfiguration.CreateConfiguration(); .private static Lazy<HttpConfiguration> CreateConfiguration()
{
Func<HttpConfiguration> arg_1F_0;
if ((arg_1F_0 = GlobalConfiguration.<>c.<>9__11_0) == null)
{
arg_1F_0 = (GlobalConfiguration.<>c.<>9__11_0 = new Func<HttpConfiguration>(GlobalConfiguration.<>c.<>9.<CreateConfiguration>b__11_0));
}
return new Lazy<HttpConfiguration>(arg_1F_0);
} .[CompilerGenerated]
[Serializable]
private sealed class <>c
{
public static readonly GlobalConfiguration.<>c <> = new GlobalConfiguration.<>c();
        ....internal HttpConfiguration <CreateConfiguration>b__11_0()
{
          //RouteTable.Routes全局路由变量
HttpConfiguration expr_0F = new HttpConfiguration(new HostedHttpRouteCollection(RouteTable.Routes));
ServicesContainer services = expr_0F.Services;
services.Replace(typeof(IAssembliesResolver), new WebHostAssembliesResolver());
services.Replace(typeof(IHttpControllerTypeResolver), new WebHostHttpControllerTypeResolver());
services.Replace(typeof(IHostBufferPolicySelector), new WebHostBufferPolicySelector());
services.Replace(typeof(IExceptionHandler), new WebHostExceptionHandler(services.GetExceptionHandler()));
return expr_0F;
} }

(2)WebApiConfig.Register方法

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务 // Web API 路由
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

由参数可知config.Routes为HostedHttpRouteCollection类型

对应MapHttpRoute方法

public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
{
if (routes == null)
{
throw Error.ArgumentNull("routes");
}
HttpRouteValueDictionary defaults2 = new HttpRouteValueDictionary(defaults);
HttpRouteValueDictionary constraints2 = new HttpRouteValueDictionary(constraints);
      //1.封装单个路由
IHttpRoute httpRoute = routes.CreateRoute(routeTemplate, defaults2, constraints2, null, handler);
      //2.把路由加入HostedHttpRouteCollection中
        routes.Add(name, httpRoute);
return httpRoute;
}

//1.封装单个路由 routes.CreateRoute方法

public override IHttpRoute CreateRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
{
if (constraints != null)
{
foreach (KeyValuePair<string, object> current in constraints)
{
this.ValidateConstraint(uriTemplate, current.Key, current.Value);
}
}
return new HostedHttpRoute(uriTemplate, defaults, constraints, dataTokens, handler);
}

可知HostedHttpRouteCollection中类型为HostedHttpRoute类型

//2.把路由加入HostedHttpRouteCollection中routes.Add方法

public override void Add(string name, IHttpRoute route)
{
this._routeCollection.Add(name, route.ToRoute());
}

从参数第4步可知_routeCollection为全局变量RouteTable.Routes中

所以webapi中路由的注册实际最后也是注册到RouteTable.Routes全局变量中

3.webapi的routehandler

根据前边可知webapi的路由最后同mvc一样都是注册到全局路由变量中,在路由中通过urlRoutingModule获取请求然后转发到对应的handler中,那么webapi对应的routehandler是什么呢?

(1).从注册的单个路由类HostedHttpRoute中

从注册路由的maphttpRoute方法中

public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults)
{
return routes.MapHttpRoute(name, routeTemplate, defaults, null, null);
} public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints)
{
return routes.MapHttpRoute(name, routeTemplate, defaults, constraints, null);
} public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
{
if (routes == null)
{
throw Error.ArgumentNull("routes");
}
HttpRouteValueDictionary defaults2 = new HttpRouteValueDictionary(defaults);
HttpRouteValueDictionary constraints2 = new HttpRouteValueDictionary(constraints);
IHttpRoute httpRoute = routes.CreateRoute(routeTemplate, defaults2, constraints2, null, handler);
routes.Add(name, httpRoute);
return httpRoute;
}

传入的handler参数都为null

在routes.CreateRoute方法中生成HostedHttpRoute调用构造函数时传入的也是null

public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
        {
           .....
      //1.封装单个路由
            IHttpRoute httpRoute = routes.CreateRoute(routeTemplate, defaults2, constraints2, null, handler);
       .....
        }
public override IHttpRoute CreateRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
{
   .......
    return new HostedHttpRoute(uriTemplate, defaults, constraints, dataTokens, handler);
}

HostedHttpRoute的构造函数

public HostedHttpRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
{
RouteValueDictionary defaults2 = (defaults != null) ? new RouteValueDictionary(defaults) : null;
RouteValueDictionary constraints2 = (constraints != null) ? new RouteValueDictionary(constraints) : null;
RouteValueDictionary dataTokens2 = (dataTokens != null) ? new RouteValueDictionary(dataTokens) : null;
this.OriginalRoute = new HttpWebRoute(uriTemplate, defaults2, constraints2, dataTokens2, HttpControllerRouteHandler.Instance, this);
this.Handler = handler;
}

hostedHttpRoute中的getdata通过调用OriginalRoute属性获取对应的routedata.

综上:webapi对应的routehandler为HttpControllerRouteHandler

可知:webapi对应的routehandler为httpControllerRouteHandler

4 webapi对应的handler

从httpControllerRouteHandler中

protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new HttpControllerHandler(requestContext.RouteData);
}

获得HttpControllerHandler.

mvc5中webapi的路由的更多相关文章

  1. Asp.Net Web API 2第八课——Web API 2中的属性路由

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 路由就是Web API如何 ...

  2. 【转】MVC5中的区域(Areas)

    MVC本身提倡的就是关注点分离.但是当项目本身的业务逻辑足够复杂,如果所有的业务逻辑都写个Controller文件夹下面的时候,你会看到非常庞大的各种命名的Controller,这个时候区域的作用就非 ...

  3. Web API 2中的属性路由

    Web API 2中的属性路由 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.ht ...

  4. MVC5中Model层开发数据注解 EF Code First Migrations数据库迁移 C# 常用对象的的修饰符 C# 静态构造函数 MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上) MVC 的HTTP请求

    MVC5中Model层开发数据注解   ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证( ...

  5. ASP.NET Web API WebHost宿主环境中管道、路由

    ASP.NET Web API WebHost宿主环境中管道.路由 前言 上篇中说到ASP.NET Web API框架在SelfHost环境中管道.路由的一个形态,本篇就来说明一下在WebHost环境 ...

  6. ASP.NET Web API Selfhost宿主环境中管道、路由

    ASP.NET Web API Selfhost宿主环境中管道.路由 前言 前面的几个篇幅对Web API中的路由和管道进行了简单的介绍并没有详细的去说明一些什么,然而ASP.NET Web API这 ...

  7. MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子

    MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子: 前端: 我们以前在前端定义了两个控件: <div class="row"> < ...

  8. 【读书笔记】Ninject 在MVC5中的使用

    从MVC3中就开始接触Ninject这个IOC工具.也一直是MVC Framework系列书籍中推荐的IOC工具,当然还有优秀的Autofac等.性能和使用上面个有千秋.下面先看一下Ninject的使 ...

  9. ASP.NET Web API 2 中的属性路由使用(转载)

    转载地址:ASP.NET Web API 2 中的属性路由使用

随机推荐

  1. django更换ORM连接处理(连接池)转

    1 概述 在使用 Django 进行 Web 开发时, 我们避免不了与数据库打交道. 当并发量低的时候, 不会有任何问题. 但一旦并发量达到一定数量, 就会导致 数据库的连接数会被瞬时占满. 这将导致 ...

  2. 使用redis实现程序或者服务的高可用

    使用redis实现程序或者服务的高可用,就是将某一程序或服务部署在不同服务器上,或者是跨机房部署,当运行服务的服务器挂了之后,其他服务器上的该服务能立马顶上,这里我简单的使用redis实现这一目的. ...

  3. Rust第一次---centos 7下的安装,配置,测试

    现在安装都依赖于网络,命令比较简单. 一,运行脚本,安装runstup 1,运行如下脚本: curl https://sh.rustup.rs -sSf | sh 2,输入默认项1,完成余下的安装 二 ...

  4. Ubuntu下部署Portainer管理docker

    在上一篇文章中,我们部署了Shipyard来管理docker集群,总体比较简单,而且Shipyard界面风格很简约,还是比较喜欢的,但是正如提出的node节点无法显示bug,以及该项目早已停止维护,让 ...

  5. 201871010133-赵永军《面向对象程序设计(java)》第八周学习总结

    201871010133-赵永军<面向对象程序设计(java)>第八周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...

  6. Selenium获取页面指定元素个数

    测试需求: 获取页面中下拉框个数,并验证是否与预期个数一致 方法1:因下拉框的tagname属性值为select,可通过获取标签为select的元素来获取下拉框个数   List<WebElem ...

  7. Git 创建点开头的文件和目录

    Git 创建点开头的文件和目录 # 创建 .gitignore 文件 1@DESKTOP-3H9092J MINGW64 /e/x1/x1/demo1 (master) $ echo .idea &g ...

  8. 大宗商品市场的未来王者 | 现货贸易商PK期货风险管理子公司

    https://mp.weixin.qq.com/s/z-kkeIor6vDb9Oer73Ct6w 大宗商品市场卧虎藏龙,参与者众多,然而能称之为王者的却寥寥无几. 在国外,以嘉能可.托克.摩科瑞为代 ...

  9. Spring Boot 2.2.0,性能提升+支持Java13

    随着 Spring Framework 5.2.0 成功发布之后,Spring Boot 2.2 也紧跟其后,发布了第一个版本:2.2.0.下面就来一起来看看这个版本都更新了些什么值得我们关注的内容. ...

  10. Web协议详解与抓包实战:HTTP1协议-HTTP 响应行(3)

    一.HTTP 响应行 二.响应码分类:1xx 三.响应码分类: 2xx 1. 201 Created: 有新资源在服务器端被成功创建 2.207 Multi-Status:RFC4918 ,在 WEB ...