Example #1
0
    protected override List <Endpoint> CreateEndpoints(
        RoutePattern?groupPrefix,
        IReadOnlyList <ActionDescriptor> actions,
        IReadOnlyList <Action <EndpointBuilder> > conventions,
        IReadOnlyList <Action <EndpointBuilder> > groupConventions)
    {
        var endpoints  = new List <Endpoint>();
        var routeNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

        for (var i = 0; i < actions.Count; i++)
        {
            if (actions[i] is PageActionDescriptor action)
            {
                _endpointFactory.AddEndpoints(endpoints,
                                              routeNames,
                                              action,
                                              Array.Empty <ConventionalRouteEntry>(),
                                              groupConventions: groupConventions,
                                              conventions: conventions,
                                              CreateInertEndpoints,
                                              groupPrefix);
            }
        }

        return(endpoints);
    }
Example #2
0
        private async Task <CompiledPageActionDescriptor> LoadAsyncCore(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata)
        {
            var viewDescriptor = await Compiler.CompileAsync(actionDescriptor.RelativePath);

            var context = new PageApplicationModelProviderContext(actionDescriptor, viewDescriptor.Type.GetTypeInfo());

            for (var i = 0; i < _applicationModelProviders.Length; i++)
            {
                _applicationModelProviders[i].OnProvidersExecuting(context);
            }

            for (var i = _applicationModelProviders.Length - 1; i >= 0; i--)
            {
                _applicationModelProviders[i].OnProvidersExecuted(context);
            }

            ApplyConventions(_conventions, context.PageApplicationModel);

            var compiled = CompiledPageActionDescriptorBuilder.Build(context.PageApplicationModel, _globalFilters);

            // We need to create an endpoint for routing to use and attach it to the CompiledPageActionDescriptor...
            // routing for pages is two-phase. First we perform routing using the route info - we can do this without
            // compiling/loading the page. Then once we have a match we load the page and we can create an endpoint
            // with all of the information we get from the compiled action descriptor.
            var endpoints = new List <Endpoint>();

            _endpointFactory.AddEndpoints(
                endpoints,
                routeNames: new HashSet <string>(StringComparer.OrdinalIgnoreCase),
                action: compiled,
                routes: Array.Empty <ConventionalRouteEntry>(),
                conventions: new Action <EndpointBuilder>[]
            {
                b =>
                {
                    // Metadata from PageActionDescriptor is less significant than the one discovered from the compiled type.
                    // Consequently, we'll insert it at the beginning.
                    for (var i = endpointMetadata.Count - 1; i >= 0; i--)
                    {
                        b.Metadata.Insert(0, endpointMetadata[i]);
                    }
                },
            },
                createInertEndpoints: false);

            // In some test scenarios there's no route so the endpoint isn't created. This is fine because
            // it won't happen for real.
            compiled.Endpoint = endpoints.SingleOrDefault();

            return(compiled);
        }
Example #3
0
        protected override List <Endpoint> CreateEndpoints(IReadOnlyList <ActionDescriptor> actions, IReadOnlyList <Action <EndpointBuilder> > conventions)
        {
            var endpoints = new List <Endpoint>();

            for (var i = 0; i < actions.Count; i++)
            {
                if (actions[i] is PageActionDescriptor action)
                {
                    _endpointFactory.AddEndpoints(endpoints, action, Array.Empty <ConventionalRouteEntry>(), conventions);
                }
            }

            return(endpoints);
        }
    protected override List <Endpoint> CreateEndpoints(IReadOnlyList <ActionDescriptor> actions, IReadOnlyList <Action <EndpointBuilder> > conventions)
    {
        var endpoints = new List <Endpoint>();
        var keys      = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

        // MVC guarantees that when two of it's endpoints have the same route name they are equivalent.
        //
        // However, Endpoint Routing requires Endpoint Names to be unique.
        var routeNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

        // For each controller action - add the relevant endpoints.
        //
        // 1. If the action is attribute routed, we use that information verbatim
        // 2. If the action is conventional routed
        //      a. Create a *matching only* endpoint for each action X route (if possible)
        //      b. Ignore link generation for now
        for (var i = 0; i < actions.Count; i++)
        {
            if (actions[i] is ControllerActionDescriptor action)
            {
                _endpointFactory.AddEndpoints(endpoints, routeNames, action, _routes, conventions, CreateInertEndpoints);

                if (_routes.Count > 0)
                {
                    // If we have conventional routes, keep track of the keys so we can create
                    // the link generation routes later.
                    foreach (var kvp in action.RouteValues)
                    {
                        keys.Add(kvp.Key);
                    }
                }
            }
        }

        // Now create a *link generation only* endpoint for each route. This gives us a very
        // compatible experience to previous versions.
        for (var i = 0; i < _routes.Count; i++)
        {
            var route = _routes[i];
            _endpointFactory.AddConventionalLinkGenerationRoute(endpoints, routeNames, keys, route, conventions);
        }

        return(endpoints);
    }
        public CompiledPageActionDescriptor Load(PageActionDescriptor actionDescriptor)
        {
            if (actionDescriptor == null)
            {
                throw new ArgumentNullException(nameof(actionDescriptor));
            }

            var compileTask    = Compiler.CompileAsync(actionDescriptor.RelativePath);
            var viewDescriptor = compileTask.GetAwaiter().GetResult();

            var context = new PageApplicationModelProviderContext(actionDescriptor, viewDescriptor.Type.GetTypeInfo());

            for (var i = 0; i < _applicationModelProviders.Length; i++)
            {
                _applicationModelProviders[i].OnProvidersExecuting(context);
            }

            for (var i = _applicationModelProviders.Length - 1; i >= 0; i--)
            {
                _applicationModelProviders[i].OnProvidersExecuted(context);
            }

            ApplyConventions(_conventions, context.PageApplicationModel);

            var compiled = CompiledPageActionDescriptorBuilder.Build(context.PageApplicationModel, _globalFilters);

            // We need to create an endpoint for routing to use and attach it to the CompiledPageActionDescriptor...
            // routing for pages is two-phase. First we perform routing using the route info - we can do this without
            // compiling/loading the page. Then once we have a match we load the page and we can create an endpoint
            // with all of the information we get from the compiled action descriptor.
            var endpoints = new List <Endpoint>();

            _endpointFactory.AddEndpoints(endpoints, compiled, Array.Empty <ConventionalRouteEntry>(), Array.Empty <Action <EndpointBuilder> >());

            // In some test scenarios there's no route so the endpoint isn't created. This is fine because
            // it won't happen for real.
            compiled.Endpoint = endpoints.SingleOrDefault();

            return(compiled);
        }
Example #6
0
    private async Task <CompiledPageActionDescriptor> LoadAsyncCore(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata)
    {
        var viewDescriptor = await Compiler.CompileAsync(actionDescriptor.RelativePath);

        var compiled = _compiledPageActionDescriptorFactory.CreateCompiledDescriptor(actionDescriptor, viewDescriptor);

        var endpoints = new List <Endpoint>();

        _endpointFactory.AddEndpoints(
            endpoints,
            routeNames: new HashSet <string>(StringComparer.OrdinalIgnoreCase),
            action: compiled,
            routes: Array.Empty <ConventionalRouteEntry>(),
            groupConventions: Array.Empty <Action <EndpointBuilder> >(),
            conventions: new Action <EndpointBuilder>[]
        {
            b =>
            {
                // Copy Endpoint metadata for PageActionActionDescriptor to the compiled one.
                // This is particularly important for the runtime compiled scenario where endpoint metadata is added
                // to the PageActionDescriptor, which needs to be accounted for when constructing the
                // CompiledPageActionDescriptor as part of the one of the many matcher policies.
                // Metadata from PageActionDescriptor is less significant than the one discovered from the compiled type.
                // Consequently, we'll insert it at the beginning.
                for (var i = endpointMetadata.Count - 1; i >= 0; i--)
                {
                    b.Metadata.Insert(0, endpointMetadata[i]);
                }
            },
        },
            createInertEndpoints: false);

        // In some test scenarios there's no route so the endpoint isn't created. This is fine because
        // it won't happen for real.
        compiled.Endpoint = endpoints.SingleOrDefault();

        return(compiled);
    }
Example #7
0
    public void RequestDelegateFactoryWorks()
    {
        // Arrange
        var values = new { controller = "TestController", action = "TestAction", page = (string)null };
        var action = CreateActionDescriptor(values, "{controller}/{action}/{page}");

        action.AttributeRouteInfo.Name = "Test";
        RequestDelegate del = context => Task.CompletedTask;
        var             requestDelegateFactory = new Mock <IRequestDelegateFactory>();

        requestDelegateFactory.Setup(m => m.CreateRequestDelegate(action, It.IsAny <RouteValueDictionary>())).Returns(del);

        // Act
        var factory = new ActionEndpointFactory(Services.GetRequiredService <RoutePatternTransformer>(), new[] { requestDelegateFactory.Object });

        var endpoints = new List <Endpoint>();

        factory.AddEndpoints(endpoints, new HashSet <string>(), action, Array.Empty <ConventionalRouteEntry>(), Array.Empty <Action <EndpointBuilder> >(), createInertEndpoints: false);

        var endpoint = Assert.IsType <RouteEndpoint>(Assert.Single(endpoints));

        // Assert
        Assert.Same(del, endpoint.RequestDelegate);
    }