前端之家收集整理的这篇文章主要介绍了
Asp.net Core MVC(四),
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
上一篇说的是asp.net mvc核心UseMvc的过程,末尾想捋一下asp.net核心的路由流转过程,现在看来还是要准备下一个代码,熟悉了代码,那么整个流转过程就通了〜
不多说,今儿先看下,RouteContext:
@H_
404_9@
private RouteData _routeData;
public RouteContext(HttpContext httpContext)
{
HttpContext =
httpContext;
RouteData =
new RouteData();
}
public RequestDelegate Handler {
get;
set; }
public HttpContext HttpContext {
get RouteData RouteData
{
{
return _routeData;
}
if (value ==
null)
{
throw ArgumentNullException(nameof(RouteData));
}
_routeData =
value;
}
}
这里可以理解RouteContext(路由子网)就是路由的环境。
其中包含三个属性器,RouteData,RequestDelegate与HttpContext。
那么什么时候设置路由的某些呢呢?
个人理解是,实在端端执行委托时,根据我们设置的路由处理程序来设置路先来看下RouteData,
@H_
404_9@
RouteValueDictionary _dataTokens;
private List<IRouter>
_routers;
RouteValueDictionary _values;
RouteValueDictionary DataTokens
{
if (_dataTokens ==
)
{
_dataTokens =
RouteValueDictionary();
}
_dataTokens;
}
}
public IList<IRouter>
Routers
{
if (_routers ==
)
{
_routers =
new List<IRouter>
();
}
_routers;
}
}
RouteValueDictionary Values
{
if (_values ==
)
{
_values =
RouteValueDictionary();
}
_values;
}
}
继续分解来看。
RouteValueDictionary DataTokens自定义传值,但不参与路由匹配。
RouteValueDictionary Values 匹配路由中的参数。
以上两者的区别在于是否参与匹配路由中的参数
RouteValueDictionary继承自IDictionary,IReadOnlyDictionary。
IList <IRouter>路由器:是参与成功匹配请求的路由的列表。
Route类作业IRouter接口的实现,使用路由模板的语法定义模式,在调用RouteAsync时匹配的URL路径。调用GetVirtualPath时,Route使用同一路由模板生成访问路径。换句话说,Route时Asp.Net Core的核心创造者。
继续往下翻代码route.cs:
@H_
404_9@
public string RouteTemplate =>
ParsedTemplate.TemplateText;
protected override Task OnRouteMatched(RouteContext context)
{
context.RouteData.Routers.Add(_target);
_target.RouteAsync(context);
}
VirtualPathData OnVirtualPathGenerated(VirtualPathContext context)
{
_target.GetVirtualPath(context);
}
OnRouteMatched方法,我们在创建路由对象时,需要建立一个路由器对象,通过该方法后,重新写入RouteData的Routers属性中 RouteData的Routers属性中,然后执行 RouteAsync方法。
@H_
404_9@
virtual Task RouteAsync(RouteContext context)
{
if (context ==
)
{
ArgumentNullException(nameof(context));
}
EnsureMatcher();
EnsureLoggers(context.HttpContext);
var requestPath =
context.HttpContext.Request.Path;
if (!
_matcher.TryMatch(requestPath,context.RouteData.Values))
{
// If we got back a null value set,that means the URI did not match
Task.CompletedTask;
}
Perf: Avoid accessing dictionaries if you don't need to write to them,these dictionaries are all
created lazily.
if (DataTokens.Count >
0)
{
MergeValues(context.RouteData.DataTokens,DataTokens);
}
RouteConstraintMatcher.Match(
Constraints,context.RouteData.Values,context.HttpContext,this,RouteDirection.IncomingRequest,_constraintLogger))
{
Task.CompletedTask;
}
_logger.RequestMatchedRoute(Name,ParsedTemplate.TemplateText);
OnRouteMatched(context);
}
@H_
404_9@
private void EnsureMatcher()
{
if (_matcher ==
)
{
_matcher =
TemplateMatcher(ParsedTemplate,Defaults);
}
}
TemplateM atcher类暂时不做过多的说明,只要知道时分析路径并匹配
RouteTemplate。(后续再看)
看到这里终于看到点路由相关的东西,通过RouteAsync我们1>确定路径与路由规则匹配; 2>通过路由模板匹配路径上的参数。
下面我们再看OnVirtualPathGenerated这个方法。
@H_
404_9@
VirtualPathData GetVirtualPath(VirtualPathContext context)
{
EnsureBinder(context.HttpContext);
EnsureLoggers(context.HttpContext);
var values =
_binder.GetValues(context.AmbientValues,context.Values);
if (values ==
We're missing one of the required values for this route.
return ;
}
;
}
context.Values =
values.CombinedValues;
var pathData =
OnVirtualPathGenerated(context);
if (pathData !=
If the target generates a value then that can short circuit.
pathData;
}
If we can produce a value go ahead and do it,the caller can check context.IsBound
to see if the values were validated.
When we still cannot produce a value,this should return null.
var virtualPath =
_binder.BindValues(values.AcceptedValues);
if (virtualPath ==
;
}
pathData =
new VirtualPathData(
if (DataTokens !=
foreach (
var dataToken
in DataTokens)
{
pathData.DataTokens.Add(dataToken.Key,dataToken.Value);
}
}
pathData;
}
方法GetVirtualPath的返回增量VirtualPathData(后续补充),
只需要知道VirtualPathData类,包含路径与虚拟路径的参考信息,也就是若要生成URL,请调用GetVirtualPath方法。该方法返回VirtualPathData类的实例,该类包含有关路由的信息。VirtualPath属性包含生成的URL。
身体不太舒服,先写到这里,下篇继续看这篇未解释的代码。
