mvc5中webapi的路由
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的路由的更多相关文章
- Asp.Net Web API 2第八课——Web API 2中的属性路由
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 路由就是Web API如何 ...
- 【转】MVC5中的区域(Areas)
MVC本身提倡的就是关注点分离.但是当项目本身的业务逻辑足够复杂,如果所有的业务逻辑都写个Controller文件夹下面的时候,你会看到非常庞大的各种命名的Controller,这个时候区域的作用就非 ...
- Web API 2中的属性路由
Web API 2中的属性路由 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.ht ...
- MVC5中Model层开发数据注解 EF Code First Migrations数据库迁移 C# 常用对象的的修饰符 C# 静态构造函数 MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上) MVC 的HTTP请求
MVC5中Model层开发数据注解 ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证( ...
- ASP.NET Web API WebHost宿主环境中管道、路由
ASP.NET Web API WebHost宿主环境中管道.路由 前言 上篇中说到ASP.NET Web API框架在SelfHost环境中管道.路由的一个形态,本篇就来说明一下在WebHost环境 ...
- ASP.NET Web API Selfhost宿主环境中管道、路由
ASP.NET Web API Selfhost宿主环境中管道.路由 前言 前面的几个篇幅对Web API中的路由和管道进行了简单的介绍并没有详细的去说明一些什么,然而ASP.NET Web API这 ...
- MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子
MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子: 前端: 我们以前在前端定义了两个控件: <div class="row"> < ...
- 【读书笔记】Ninject 在MVC5中的使用
从MVC3中就开始接触Ninject这个IOC工具.也一直是MVC Framework系列书籍中推荐的IOC工具,当然还有优秀的Autofac等.性能和使用上面个有千秋.下面先看一下Ninject的使 ...
- ASP.NET Web API 2 中的属性路由使用(转载)
转载地址:ASP.NET Web API 2 中的属性路由使用
随机推荐
- itextpdf确定页面坐标的方式
itextpdf的确定页面上的具体坐标是通过坐标来确定的. 它们的坐标轴是这样的:以左下角为原点的xy坐标轴. 在itextpdf的方法中中,定义某个点的位置,都是以左下方为原点坐标轴来确定. 如果要 ...
- unsigned int数据类型最大数
#include <stdio.h> int main() { unsigned , b = ; ) { a++; } printf( ); unsigned ; do { n = n / ...
- 8-剑指offer: 替换空格
题目描述 请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 代码: c ...
- 201871010136-赵艳强《面向对象程序设计(Java)》第八周学习总结
201871010136-赵艳强<面向对象程序设计(Java)>第八周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...
- wafer2的keng
一.之前用wafer2开发的小程序,今天突然Error: 用户未登录过,请先使用 login() 登录? 答:改用qcloud.login, 替换掉qcloud.loginWithCode (小程序代 ...
- JavaScript中的this—你不知道的JavaScript上卷读书笔记(三)
this是什么? this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件.this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式.当一个函数被调用时,会 ...
- web框架--tornado之验证码实例
tornado随机生成图片验证码 用python生成随机验证码需要借鉴一个插件,和一个io模块,实现起来也非常容易,当然也需要借鉴session来判断验证码是否错误,下面写一段用户登录验证带验证码的. ...
- Function.prototype.call.bind
在JavaScript中借用方法 在JavaScript中,有时候需要在一个不同的对象上重用一个函数,而不是在定义它的对象或者原型中.通过使用call(),applay()和bind(),我们可以很方 ...
- PATB1033 旧键盘打字 (20 分)
一.技术总结 使用字符数组出现段错误即char str[];改成string str:后问题解决.以后尽量使用C++中的string 使用cin>>,出现答案错误,原因可能是在输入是有空格 ...
- ZJOI 2009 多米诺骨牌(状态压缩+轮廓线+容斥)
题意 https://www.lydsy.com/JudgeOnline/problem.php?id=1435 思路 一道很好的状压/容斥题,涵盖了很多比较重要的知识点. 我们称每两行间均有纵跨.每 ...