asp.net core 终结点 Action

 asp.net core 终结点是怎么匹配Action的呢,先从启动程序开始

 net core 3 时代 

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});

 6.0 默认的终结点匹配简化:

app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");

再看 MapControllerRoute的源码如下:

复制代码
public static ControllerActionEndpointConventionBuilder MapControllerRoute(
            this IEndpointRouteBuilder endpoints,
            string name,
            string pattern,
            object? defaults = null,
            object? constraints = null,
            object? dataTokens = null)
        {
            if (endpoints == null)
            {
                throw new ArgumentNullException(nameof(endpoints));
            }
            EnsureControllerServices(endpoints); //MvcMarkerService
            var dataSource = GetOrCreateDataSource(endpoints); 
            return dataSource.AddRoute(
                name,
                pattern,
                new RouteValueDictionary(defaults),
                new RouteValueDictionary(constraints),
                new RouteValueDictionary(dataTokens));
        }
复制代码
复制代码
     private static ControllerActionEndpointDataSource GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
        {
            var dataSource = endpoints.DataSources.OfType<ControllerActionEndpointDataSource>().FirstOrDefault();
            if (dataSource == null)
            {
                var orderProvider = endpoints.ServiceProvider.GetRequiredService<OrderedEndpointsSequenceProviderCache>();
                var factory = endpoints.ServiceProvider.GetRequiredService<ControllerActionEndpointDataSourceFactory>();
                dataSource = factory.Create(orderProvider.GetOrCreateOrderedEndpointsSequenceProvider(endpoints));
                endpoints.DataSources.Add(dataSource);
            }
            return dataSource;
        }
复制代码

 如上图 从service中获取ControllerActionEndpointDataSource实例的时候,也会初始化ControllerActionDescriptorProvider和DefaultActionDescriptorCollectionProvider,

ControllerActionEndpointDataSource的构造函数如下

复制代码
    public ControllerActionEndpointDataSource(
            ControllerActionEndpointDataSourceIdProvider dataSourceIdProvider,
            IActionDescriptorCollectionProvider actions,
            ActionEndpointFactory endpointFactory,
            OrderedEndpointsSequenceProvider orderSequence)
            : base(actions)
        {
            _endpointFactory = endpointFactory;

            DataSourceId = dataSourceIdProvider.CreateId();
            _orderSequence = orderSequence;
            _routes = new List<ConventionalRouteEntry>();
            DefaultBuilder = new ControllerActionEndpointConventionBuilder(Lock, Conventions);
            // IMPORTANT: this needs to be the last thing we do in the constructor.
            // Change notifications can happen immediately!
            Subscribe();
        }
复制代码

Subscribe 会调用到DefaultActionDescriptorCollectionProvider对象的UpdateCollection 执行ControllerActionDescriptorProvider的如下方法,实现把Action加入到ActionDescriptorProviderContext中

复制代码
       public void OnProvidersExecuting(ActionDescriptorProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            foreach (var descriptor in GetDescriptors())
            {
                context.Results.Add(descriptor);
            }
        }
        internal IEnumerable<ControllerActionDescriptor> GetDescriptors()
        {
            var controllerTypes = GetControllerTypes();
            var application = _applicationModelFactory.CreateApplicationModel(controllerTypes);
            return ControllerActionDescriptorBuilder.Build(application);
        }
复制代码

 

作者:RunStone

出处:https://www.cnblogs.com/RunStone/p/16805211.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   奔跑石头  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示