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 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); }