目录

  1. ASP.NET 路由

    • 注册路由

    • 动态映射HttpHandler

  2. WebAPI 路由

    • 注册路由

    • 调用GetRouteData

  3. 2个路由系统衔接

    • GlobalConfiguration

    • HostedHttpRoute

  4. 补充

路由是进入Web API的第一扇门.目的用于确定Controller名称、Action名称、路由参数.

ASP.NET 路由

注册路由

在ASP.NET中注册路由的方式:

RouteCollection.MapPageRoute()

添加1个完整的路由:

var defaults = new RouteValueDictionary//路由变量默认值
{
{"code","010"},
{"phone","1000000"},
};
var constraints = new RouteValueDictionary//路由变量约束
{
{"code",@"0\d{2,3}" },
{"phone",@"\d{7,9}" },
{"httpMethod",new HttpMethodConstraint("POST") }
};
var dataTokens = new RouteValueDictionary//路由相关参数,不用于处理路由匹配功能
{
{"defaultCode","北京" },
{"defaultPhone","北京X电话" }
};
RouteTable.Routes.MapPageRoute("default", "{code}/{phone}", "~/call.aspx", false, defaults, constraints, dataTokens);

获取RouteCollection

一般通过RouteTable.Routes

public class RouteTable
{
private static RouteCollection _instance = new RouteCollection(); public static RouteCollection Routes { get { return RouteTable._instance; } }
}

路由:RouteBase

public abstract class RouteBase
{
public bool RouteExistingFiles {get; set;} = true;//对现有文件进行路由
public abstract RouteData GetRouteData(HttpContextBase httpContext);
public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}

路由默认实现:Route

public class Route : RouteBase
{
/// <summary>
/// 路由约束
/// </summary>
public RouteValueDictionary Constraints { get; set; }
/// <summary>
/// 路由自定义参数(一般存储备注说明等)
/// </summary>
public RouteValueDictionary DataTokens { get; set; }
/// <summary>
/// 路由变量默认值
/// </summary>
public RouteValueDictionary Defaults { get; set; }
/// <summary>
/// 路由对应处理程序对象
/// </summary>
public IRouteHandler RouteHandler { get; set; }
/// <summary>
/// 路由模板
/// </summary>
public string Url { get; set; }
}

忽略路由:

忽略路由本质是添加一个StopRoutingHandler(返回空的HttpHandler)的路由

routes.Ignore("010/1000001");(路由先注册,先匹配)
routes.MapPageRoute("default", "{code}/{phone}", "~/call.aspx", false, defaults, constraints, dataTokens);

路由约束:

在上面完整的路由添加Demo中,路由约束有2种方式

  1. 正则表达式字符串
  2. 实现IRouteConstraint接口

动态映射HttpHandler

路由是通过UrlRoutingModule这个HttpModule实现动态拦截.

public virtual void PostResolveRequestCache(HttpContextBase context)
{
RouteData routeData = RouteTable.Routes.GetRouteData(context);
IRouteHandler routeHandler = routeData.RouteHandler;
IHttpHandler httpHandler = routeHandler.GetHttpHandler(new RequestContext(context, routeData));
context.RemapHandler(httpHandler);
}

WebAPI 路由

注册路由

在Web API中注册路由的方式:HttpRouteCollection.MapHttpRoute(),

这里重点看下MapHttpRoute方法内部

public static class HttpRouteCollectionExtensions
{
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
{
IHttpRoute route = routes.CreateRoute(routeTemplate, (IDictionary<string, object>)defaults, (IDictionary<string, object>)constraints, (IDictionary<string, object>)null, handler);
routes.Add(name, route);
return route;
}
}

获取HttpRouteCollection

在WebAPI中通过HttpConfiguration的Routes属性

public class HttpConfiguration : IDisposable
{
public Collection<DelegatingHandler> MessageHandlers { get; }
public HttpRouteCollection Routes { get; }
public ConcurrentDictionary<object, object> Properties { get; }
}

WebAPI路由:IHttpRoute

public interface IHttpRoute
{
string RouteTemplate { get; } IDictionary<string, object> Defaults { get; } IDictionary<string, object> Constraints { get; } IDictionary<string, object> DataTokens { get; } HttpMessageHandler Handler { get; } IHttpRouteData GetRouteData(string virtualPathRoot, HttpRequestMessage request); IHttpVirtualPathData GetVirtualPath(HttpRequestMessage request, IDictionary<string, object> values);
}

WebAPI路由默认实现:HttpRoute

由于IHttpRoute设计的非常全,HttpRoute基本就是实现了IHttpRoute.

(这种设计上比RouteBase要优势很多)

调用GetRouteData

与ASP.NET稍微不同的是

  1. 直接对所有请求进行路由 而不再判断是否文件存在.
  2. 添加一个VirtualPathRoot的过滤
public class HttpRouteCollection
{
public virtual IHttpRouteData GetRouteData(HttpRequestMessage request)
{
string virtualPathRoot = request.GetRequestContext().VirtualPathRoot;
IHttpRouteData routeData = this._collection[index].GetRouteData(virtualPathRoot, request);
return routeData;
}
}

2个路由系统衔接

Web API提供了一套自身的路由系统,所以不依赖于ASP.NET.

寄宿方式有多种.如果以WebHost的方式.本质上还是走的ASP.NET路由处理.

GlobalConfiguration

WebAPI的配置在HttpConfiguration中提供.

在WebHost中,定义了GlobalConfiguration用来创建HttpConfiguration

public static class GlobalConfiguration

{

public static HttpConfiguration Configuration = GlobalConfiguration.CreateConfiguration();//创建HttpConfiguration

public static HttpMessageHandler DefaultHandler = GlobalConfiguration.CreateDefaultHandler();//创建HttpRoutingDispatcher(WebAPI管道尾部HttpMessageHandler)

public static HttpServer DefaultServer = GlobalConfiguration.CreateDefaultServer();//创建HttpServer(WebAPI管道开头HttpMessageHandler)

public static void Configure(Action<HttpConfiguration> configurationCallback)//提供方便配置路由
{
configurationCallback(GlobalConfiguration.Configuration);
} private static Lazy<HttpConfiguration> CreateConfiguration()
{
return new Lazy<HttpConfiguration>((Func<HttpConfiguration>) (() =>
{
//这里用HostedHttpRouteCollection实现HttpRouteCollection
return new HttpConfiguration((HttpRouteCollection) new HostedHttpRouteCollection(RouteTable.Routes));
}));
}

}

HostedHttpRoute

在GlobalConfiguration中创建的HttpConfiguration对象是用HostedHttpRouteCollection作为参数

这里我觉得有必要看下CreateRoute和Add方法

internal class HostedHttpRouteCollection : HttpRouteCollection
{
//真正维护的路由集合
private readonly RouteCollection _routeCollection; //创建路由 MapHttpRoute会调用该方法
public override IHttpRoute CreateRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
{
return (IHttpRoute) new HostedHttpRoute(uriTemplate, defaults, constraints, dataTokens, handler);
} public override void Add(string name, IHttpRoute route)
{
//只是添加到内部的routeCollection中
//route.ToRoute() => route.OriginalRoute;
this._routeCollection.Add(name, (RouteBase) route.ToRoute());
} public override IHttpRouteData GetRouteData(HttpRequestMessage request)
{
//通过调用内部的Route的GetRouteData
RouteData routeData = this._routeCollection.GetRouteData(httpContextBase);
return (IHttpRouteData)new HostedHttpRouteData(routeData);
}
}

而HostedHttpRoute在WebHost中

相当于用HttpRoute的身 却提供了真正的Route

internal class HostedHttpRoute : IHttpRoute
{
//ASP.NET Route
internal Route OriginalRoute { get; private set; } public HostedHttpRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
{
//内部的OriginalRoute实际为HttpWebRoute
this.OriginalRoute = (Route) new HttpWebRoute(uriTemplate, defaults1, constraints1, dataTokens1, <strong>(IRouteHandler) HttpControllerRouteHandler.Instance</strong>, (IHttpRoute) this);
this.Handler = handler;
}
}

从HostedHttpRoute构造函数中 我们看到了真正的Route为HttpWebRoute 且RouteHandler为HttpControllerRouteHandler.Instance

public class HttpControllerRouteHandler : IRouteHandler
{
public static HttpControllerRouteHandler Instance{ get { return new HttpControllerRouteHandler(); } } protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return (IHttpHandler) new HttpControllerHandler(requestContext.RouteData);
}
}

补充

冗余的设计:

  • HttpRoute中Handler的HttpMessageHandler,未发现有任何地方使用到.

  • HttpRoute和Route中DataTokens,建议直接取消.

备注:

  • 文章中的代码并非完整,一般是经过自己精简后的.

  • 本篇内容使用MarkDown语法编辑

首发地址:http://neverc.cnblogs.com/p/5933752.html

[Web API] Web API 2 深入系列(1) 路由的更多相关文章

  1. ASP.NET Web API - ASP.NET MVC 4 系列

           Web API 项目是 Windows 通信接口(Windows Communication Foundation,WCF)团队及其用户激情下的产物,他们想与 HTTP 深度整合.WCF ...

  2. 如何用Baas快速在腾讯云上开发小程序-系列1:搭建API & WEB WebSocket 服务器

    版权声明:本文由贺嘉 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221059001487422606 来源:腾云阁 h ...

  3. Java web与web gis学习笔记(二)——百度地图API调用

    系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...

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

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

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

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

  6. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)

    1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息.   但是c ...

  7. 我所理解的RESTful Web API [Web标准篇]

    REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...

  8. 重构Web Api程序(Api Controller和Entity)续篇

    昨天有写总结<重构Web Api程序(Api Controller和Entity)>http://www.cnblogs.com/insus/p/4350111.html,把一些数据交换的 ...

  9. web api写api接口时返回

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...

随机推荐

  1. (转载)H.264码流的RTP封包说明

    H.264的NALU,RTP封包说明(转自牛人) 2010-06-30 16:28 H.264 RTP payload 格式 H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) ...

  2. 跟服务器交互的登录Demo

    服务器写死 账号密码,演示登录 服务器代码: 开发工具MyEclipse public class LoginServlet extends HttpServlet { /** * The doGet ...

  3. Building Modern Web Apps-构建现代的 Web 应用程序(一些感想)

    <iframe src="http://channel9.msdn.com/Series/MVA-China/Web20140611A01/player?h=540&w=960 ...

  4. ASP.NET Web API 2.1支持Binary JSON(Bson)

    ASP.NET Web API 2.1内建支持XML.Json.Bson.form-urlencoded的MiME type,今天重点介绍下Bson.BSON是由10gen开发的一个数据格式,目前主要 ...

  5. SQLite 预写式日志

    SQLite在3.7.0版本引入了WAL (Write-Ahead-Logging),WAL的全称是Write Ahead Logging,它是很多数据库中用于实现原子事务的一种机制,引入WAL机制之 ...

  6. ARM汇编指令调试方法

    学习ARM汇编时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在 ...

  7. [ASP.NET MVC 小牛之路]02 - C#知识点提要

    本人博客已转移至:http://www.exblr.com/liam  本篇博文主要对asp.net mvc开发需要撑握的C#语言知识点进行简单回顾,尤其是C# 3.0才有的一些C#语言特性.对于正在 ...

  8. HTTPS那些事(一)HTTPS原理(转载)

    原创地址:http://www.guokr.com/post/114121/   楔子 谣言粉碎机前些日子发布的<用公共WiFi上网会危害银行账户安全吗?>,文中介绍了在使用HTTPS进行 ...

  9. 分析nuget源码,用nuget + nuget.server实现winform程序的自动更新

    源起 (个人理解)包管理最开始应该是从java平台下的maven开始吧,因为java的开发大多数是基于开源组件开发的,一个开源包在使用时很可能要去依赖其他的开源包,而且必须是特定的版本才可以.以往在找 ...

  10. 未找到与约束 ContractName Microsoft.VisualStudio.Text.ITextBufferFactoryService RequiredTypeIdentity Microsoft.VisualStudio.Text.ITextBufferFactoryService

    问题:vs2013在装了 之后,重启,打开VS提示: 未找到与约束 ContractName Microsoft.VisualStudio.Text.ITextBufferFactoryService ...