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. IEDA创建Springboot项目

    随着技术的更新对于开发速度的追求,我们越来越不能忍受的是Spring框架对于集成开发以后大量的配置问题.所以SprigBoot应运而生,SpringBoot框架其实就是在Spring框架的外边包裹上了 ...

  2. Linux CentOs基本命令

    基本操作(命令模式下) yy --复制光标所在行 nyy --n为数字,复制光标所在向下n行 p --粘贴到光标的下一行 P --贴在光标的上一行 G --光标移到文件末尾 gg --光标移到文件头 ...

  3. Mac环境下 jieba 配置记录

    在终端里输入: pip3 install jieba -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

  4. 【转载】Innodb中的事务隔离级别和锁的关系

    前言 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所 ...

  5. 学习:API断点和条件记录断点和内存断点的配合

    前言:感觉可能与之前有点相同,主要是介绍shark恒老师说的一种断点方法,结合了API和条件记录进行下断点 适用条件:当我们利用简单的WINDOWS API函数如MessageBoxW/A 又或者获取 ...

  6. How to display `top` results sorted by memory usage in real time?

    If you're using the top that comes with Ubuntu (top -v = procps-ng version 3.3.10), then you can use ...

  7. Bootstrap-table实现动态合并相同行

    Bootstrap-table  表格合并相同名字的列 @编写function() /** * 合并行 * @param data 原始数据(在服务端完成排序) * @param fieldName ...

  8. JavaScript (JS)常用方法

    被按的按键的 unicode 是? <html> <head> <script type="text/javascript"> function ...

  9. Java代码中对IP进行白名单验证

    来自:https://www.cnblogs.com/shinubi/p/6723003.html public class ipUtil { // IP的正则,这个正则不能验证第一组数字为0的情况 ...

  10. sql实现excel中模糊替换

    今天遇到项目上需要修改数据库中部分字段 如果一个一个替换的话工作量实在太大,于是找一个办法 update 表名 set 字段名=replace(字段名,'aaaa','cccc') + whereaa ...