public void OnProvidersExecuting(ActionDescriptorProviderContext context) { var newContext = new ActionDescriptorProviderContext(); _pageActionDescriptorProvider.OnProvidersExecuting(newContext); _pageActionDescriptorProvider.OnProvidersExecuted(newContext); var feature = new ViewsFeature(); _applicationPartManager.PopulateFeature(feature); var lookup = new Dictionary <string, CompiledViewDescriptor>(feature.ViewDescriptors.Count, StringComparer.Ordinal); foreach (var viewDescriptor in feature.ViewDescriptors) { // View ordering has precedence semantics, a view with a higher precedence was not // already added to the list. lookup.TryAdd(ViewPath.NormalizePath(viewDescriptor.RelativePath), viewDescriptor); } foreach (var item in newContext.Results) { var pageActionDescriptor = (PageActionDescriptor)item; if (!lookup.TryGetValue(pageActionDescriptor.RelativePath, out var compiledViewDescriptor)) { throw new InvalidOperationException($"A descriptor for '{pageActionDescriptor.RelativePath}' was not found."); } var compiledPageActionDescriptor = _compiledPageActionDescriptorFactory.CreateCompiledDescriptor( pageActionDescriptor, compiledViewDescriptor); context.Results.Add(compiledPageActionDescriptor); } }
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); }