Java教程

Web API源码笔记-路由信息

本文主要是介绍Web API源码笔记-路由信息,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.路由基本介绍

由于之前分析过详细的源码单步解析,所以这里不再每一步探究具体的细节,而是上升一个层面以总结和回顾的形式来看待
在webapi中是采用先将路由和处理程序注册,在处理请求时根据路由信息找到处理程序,注册流程如下

一个web应用有一个全局的路由表,并通过RouteTable.Route来表示,它的返回值类型是一个继承自Collection的RouteCollection类型,在应用初始化时将路由规则直接或者间接的添加到路由表中。

1.Web Form中的路由绑定

web Form中添加路由是最直观的阐述了上面的介绍,因为在webform中我们直接使用RouteCollection类型的实例方法MapPageRoute就可以了,而在web API应用中是有点不一样的。

var Routes = RouteTable.Routes;
Routes.MapPageRoute("", "Test/{name}/{id}","~/default.aspx", true, defaults);
2.Web API中的路由绑定

WEB Api注册路由入口

 public static void Register(HttpConfiguration config)
 {
     config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = RouteParameter.Optional }
     );    
 }
 
 protected void Application_Start()
 {
     GlobalConfiguration.Configure(WebApiConfig.Register);
 }

这里的config.Routes就是一个HttpRouteCollection对象

在webapi中绑定路由,其实最终也是绑定到全局路由表RouteTable上,但是过程却稍微间接一些,是通过一个类型为HttpRouteCollection或者继承自它的实例扩展方法来进行绑定的.

1.首先在webapi应用初始化时默认创建了继承自HttpRouteCollection类型的HostedHttpRouteCollection的实例并将全局路由表RouteTable.Routes传入

2.返回一个HttpConfiguration的实例config作为WebApiConfig.Register的参数,然后调用扩展方法来添加路由到RouteTable上,当然其中有一些细节是不一样的,目前先省略

3.顺便说一下包括路由注册在内对整个Web API管道的配置都是通过HttpConfiguration来完成的,一切可以从GlobalConfiguration静态类中找到答案

3.HostedHttpRouteCollection

由于web API框架是一个抽象的消息处理管道,具有自己的路由系统,并且它是由一系列注册实现了IHttpRoute接口的HttpRoute对象组成

1.在GlobalConfiguration中的CreateConfiguration方法返回的我们可以看到HttpConfiguration包含的类型是一个HostedHttpRouteCollection类型.

 private static Lazy<HttpConfiguration> CreateConfiguration()
 {
    return new Lazy<HttpConfiguration>(() =>
       {
           HttpConfiguration config = null;
           var newInstance = new HostedHttpRouteCollection(RouteTable.Routes);
           config = new HttpConfiguration(newInstance);
           return config;
       });
}

2.包含在HostedHttpRouteCollection之中的创建出的Route类型是一个HostedHttpRoute

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);
}     

3.在HostedHttpRouteCollection中有一个RouteCollection类型的字段_routeCollection 并且在初始化时将RouteTable.Routes传递给了它

public HostedHttpRouteCollection(RouteCollection routeCollection)
    : this(routeCollection, virtualPathRoot: null)
{
}
public HostedHttpRouteCollection(RouteCollection routeCollection, string virtualPathRoot)
{
    _routeCollection = routeCollection;
    _virtualPathRoot = virtualPathRoot;
}

4.在类中重写了Add方法,它会将指定的HttpRoute对象转为Route,并且添加到ASP.NET的全局路由表中,到这里说明在webapi webHost中依然还是采用的ASP.NET路由,只不过在实现上做了一些调整

 public override void Add(string name, IHttpRoute route)
 {
     _routeCollection.Add(name, route.ToRoute());
 }
4.HttpControllerRouteHanlder和HttpControllerHanlder

1.通过原来的学习我们知道,在ASP .NET中整个路由的核心是UrlRoutingModule的HttpModule,在UrlRoutingModule中根据请求上下文得到当前路由的路由处理程序IRouteHandler

UrlRoutingModule处理代码

 public virtual void PostResolveRequestCache(HttpContextBase context)
 {
     //根据请求获取注册的路由信息
     RouteData routeData = RouteCollection.GetRouteData(context);
     //获取到路由信息的路由处理程序
     IRouteHandler routeHandler = routeData.RouteHandler;
     RequestContext requestContext = new RequestContext(context, routeData);
     context.Request.RequestContext = requestContext;
     //由路由处理程序得到具体处理的HttpHanlder
     IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
 }

2.此时得到的是一个HttpControllerRouteHandler对象的路由处理程序,然后在根据路由处理程序获取到HttpControllerHandler,最终处理由HttpControllerHandler中的ProcessRequestAsyncCore方法处理,也同时标志此时请求将正式被WEB Api管道接管开始执行

 internal async Task ProcessRequestAsyncCore(HttpContextBase contextBase)
 {
    HttpRequestMessage request = contextBase.GetHttpRequestMessage() ?? ConvertRequest(contextBase);

    HttpResponseMessage response = null;

    try
    {
        //开始进入管道
       response = await _server.SendAsync(request, cancellationToken);
              
    }
    catch (OperationCanceledException)
    {
           
    }
   finally
   {
          
   }
}
这篇关于Web API源码笔记-路由信息的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!