Asp.net Core MVC四

上一篇说的是asp.net mvc核心UseMvc的过程,末尾想捋一下asp.net核心的路由流转过程,现在看来还是要准备下一个代码,熟悉了代码,那么整个流转过程就通了〜

不多说,今儿先看下,RouteContext:

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,

 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:

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方法。

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);
}
private void EnsureMatcher()
{
    if (_matcher == )
    {
        _matcher =  TemplateMatcher(ParsedTemplate,Defaults);
    }
}

TemplateM atcher类暂时不做过多的说明,只要知道时分析路径并匹配

 RouteTemplate。(后续再看)

看到这里终于看到点路由相关的东西,通过RouteAsync我们1>确定路径与路由规则匹配; 2>通过路由模板匹配路径上的参数。

 

下面我们再看OnVirtualPathGenerated这个方法。

 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。

 

身体不太舒服,先写到这里,下篇继续看这篇未解释的代码。

 

 

相关文章

在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示...
上文已经介绍了Identity Service的实现过程。今天我们继续,...
最近我为我自己的应用开发框架Apworks设计了一套案例应用程序...
HAL(Hypertext Application Language,超文本应用语言)是一...
在前面两篇文章中,我详细介绍了基本事件系统的实现,包括事...
HAL,全称为Hypertext Application Language,它是一种简单的...