snapshot.Restore() 重新初始化快照状态。
接下来就要看具体的路由处理对象了,我们从 RouteBase 开始。
1、RouteBase 的构造函数会初始化 RouteTemplate, Name, DataTokens, Defaults.
Defaults 是默认配置的路由参数。
2、RouteAsync 中会进行一系列检查,如果没有匹配到URL对应的路由就会直接返回。
3、使用路由参数匹配器 RouteConstraintMatcher 进行匹配,如果没有匹配到,同样直接返回。
4、如果匹配成功,会触发 OnRouteMatched(RouteContext context)函数,它是一个抽象函数,具体实现位于 Route.cs 中。
然后,我们再继续跟踪到 Route.cs 中的 OnRouteMatch,一起来看一下:
protected override Task OnRouteMatched(RouteContext context)
{
context.RouteData.Routers.Add(_target);
return _target.RouteAsync(context);
}
_target 值得当前路由的处理程序,那么具体是哪个路由处理程序呢? 我们一起探索一下。
我们知道,我们创建路由一共有MapRoute,MapGet,MapPost,MapPut,MapDelete,MapVerb... 等等这写方式,我们分别对应说一下每一种它的路由处理程序是怎么样的,下面是一个示例:
app.UseRouter(routes =>{
routes.DefaultHandler = new RouteHandler((httpContext) =>
{
var request = httpContext.Request;
return httpContext.Response.WriteAsync($"");
});
routes
.MapGet("api/get/{id}", (request, response, routeData) => {})
.MapMiddlewareRoute("api/middleware", (appBuilder) =>
appBuilder.Use((httpContext, next) => httpContext.Response.WriteAsync("Middleware!")
))
.MapRoute(
name: "AllVerbs",
template: "api/all/{name}/{lastName?}",
defaults: new { lastName = "Doe" },
constraints: new { lastName = new RegexRouteConstraint(new Regex("[a-zA-Z]{3}",RegexOptions.CultureInvariant, RegexMatchTimeout)) });
});
按照上面的示例解释一下,
MapRoute:使用这种方式的话,必须要给 DefaultHandler 赋值处理程序,否则会抛出异常,通常情况下我们会使用RouteHandler类。
MapVerb: MapPost,MapPut 等等都和它类似,它将处理程序作为一个 RequestDelegate 委托提供了出来,也就是说我们实际上在自己处理HttpContext的东西,不会经过RouteHandler处理。
MapMiddlewareRoute:需要传入一个 IApplicationBuilder 委托,实际上 IApplicationBuilder Build之后也是一个 RequestDelegate,它会在内部 new 一个 RouteHandler 类,然后调用的 MapRoute。
这些所有的矛头都指向了 RouteHandler , 我们来看看 RouteHandler








