using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Matching; namespace zero.Routing; // see https://github.com/umbraco/Umbraco-CMS/blob/5bfab13dc5a268714aad2426a2b68ab5561a6407/src/Umbraco.Web.Website/Routing/NotFoundSelectorPolicy.cs /// /// Used to handle 404 routes that haven't been handled by the end user /// public class NotFoundSelectorPolicy : MatcherPolicy, IEndpointSelectorPolicy { //private readonly Lazy _notFound; private readonly EndpointDataSource _endpointDataSource; public NotFoundSelectorPolicy(EndpointDataSource endpointDataSource) { //_notFound = new Lazy(GetNotFoundEndpoint); _endpointDataSource = endpointDataSource; } // return the endpoint for the RenderController.Index action. //private Endpoint GetNotFoundEndpoint() //{ // Endpoint e = _endpointDataSource.Endpoints.First(x => // { // // return the endpoint for the RenderController.Index action. // ControllerActionDescriptor descriptor = x.Metadata?.GetMetadata(); // return descriptor?.ControllerTypeInfo == typeof(RenderController) // && descriptor?.ActionName == nameof(RenderController.Index); // }); // return e; //} public override int Order => 0; public bool AppliesToEndpoints(IReadOnlyList endpoints) { // Don't apply this filter to any endpoint group that is a controller route // i.e. only dynamic routes. foreach (Endpoint endpoint in endpoints) { ControllerAttribute controller = endpoint.Metadata?.GetMetadata(); if (controller != null) { return false; } } // then ensure this is only applied if all endpoints are IDynamicEndpointMetadata return endpoints.All(x => x.Metadata?.GetMetadata() != null); } public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates) { if (AllInvalid(candidates)) { //UmbracoRouteValues umbracoRouteValues = httpContext.Features.Get(); //if (umbracoRouteValues?.PublishedRequest != null // && !umbracoRouteValues.PublishedRequest.HasPublishedContent() // && umbracoRouteValues.PublishedRequest.ResponseStatusCode == StatusCodes.Status404NotFound) //{ // // not found/404 // httpContext.SetEndpoint(_notFound.Value); //} } return Task.CompletedTask; } private static bool AllInvalid(CandidateSet candidates) { for (int i = 0; i < candidates.Count; i++) { if (candidates.IsValidCandidate(i)) { return false; } } return true; } }