diff --git a/src/Umbraco.Web.BackOffice/Install/InstallController.cs b/src/Umbraco.Web.BackOffice/Install/InstallController.cs index ca29a508c4..a773a6f5a1 100644 --- a/src/Umbraco.Web.BackOffice/Install/InstallController.cs +++ b/src/Umbraco.Web.BackOffice/Install/InstallController.cs @@ -13,6 +13,7 @@ using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.WebAssets; using Umbraco.Cms.Infrastructure.Install; +using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Filters; using Umbraco.Extensions; @@ -101,6 +102,7 @@ namespace Umbraco.Cms.Web.BackOffice.Install /// /// [HttpGet] + [IgnoreFromNotFoundSelectorPolicy] public ActionResult Redirect() { var uri = HttpContext.Request.GetEncodedUrl(); diff --git a/src/Umbraco.Web.Common/Attributes/IgnoreFromNotFoundSelectorPolicyAttribute.cs b/src/Umbraco.Web.Common/Attributes/IgnoreFromNotFoundSelectorPolicyAttribute.cs new file mode 100644 index 0000000000..8fad2b6c6b --- /dev/null +++ b/src/Umbraco.Web.Common/Attributes/IgnoreFromNotFoundSelectorPolicyAttribute.cs @@ -0,0 +1,13 @@ +using System; + +namespace Umbraco.Cms.Web.Common.Attributes +{ + /// + /// When applied to an api controller it will be routed to the /Umbraco/BackOffice prefix route so we can determine if it + /// is a back office route or not. + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public sealed class IgnoreFromNotFoundSelectorPolicyAttribute : Attribute + { + } +} diff --git a/src/Umbraco.Web.Website/Routing/NotFoundSelectorPolicy.cs b/src/Umbraco.Web.Website/Routing/NotFoundSelectorPolicy.cs index dbc06175fd..871ae75d33 100644 --- a/src/Umbraco.Web.Website/Routing/NotFoundSelectorPolicy.cs +++ b/src/Umbraco.Web.Website/Routing/NotFoundSelectorPolicy.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Matching; using Umbraco.Cms.Core.Routing; +using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Controllers; using Umbraco.Cms.Web.Common.Routing; @@ -35,7 +36,7 @@ namespace Umbraco.Cms.Web.Website.Routing // return the endpoint for the RenderController.Index action. ControllerActionDescriptor descriptor = x.Metadata?.GetMetadata(); return descriptor?.ControllerTypeInfo == typeof(RenderController) - && descriptor?.ActionName == nameof(RenderController.Index); + && descriptor?.ActionName == nameof(RenderController.Index); }); return e; } @@ -45,7 +46,7 @@ namespace Umbraco.Cms.Web.Website.Routing public bool AppliesToEndpoints(IReadOnlyList endpoints) { // Don't apply this filter to any endpoint group that is a controller route - // i.e. only dynamic routes. + // i.e. only dynamic routes. foreach (Endpoint endpoint in endpoints) { ControllerAttribute controller = endpoint.Metadata?.GetMetadata(); @@ -80,11 +81,15 @@ namespace Umbraco.Cms.Web.Website.Routing { for (int i = 0; i < candidates.Count; i++) { - if (candidates.IsValidCandidate(i)) + // We have to check if candidates needs to be ignored here + // So we dont return false when all endpoints are invalid + if (candidates.IsValidCandidate(i) && + candidates[i].Endpoint.Metadata.GetMetadata() is null) { return false; } } + return true; } }