diff --git a/src/Umbraco.Web/Actions/ActionCollection.cs b/src/Umbraco.Web/Actions/ActionCollection.cs index 64cf950c60..89ac8a59f4 100644 --- a/src/Umbraco.Web/Actions/ActionCollection.cs +++ b/src/Umbraco.Web/Actions/ActionCollection.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Globalization; using System.Linq; using Umbraco.Core; using Umbraco.Core.Composing; @@ -22,19 +21,21 @@ namespace Umbraco.Web.Actions internal IEnumerable GetByLetters(IEnumerable letters) { - var all = this.ToArray(); - return letters.Select(x => all.FirstOrDefault(y => y.Letter.ToString(CultureInfo.InvariantCulture) == x)) + var actions = this.ToArray(); // no worry: internally, it's already an array + return letters + .Where(x => x.Length == 1) + .Select(x => actions.FirstOrDefault(y => y.Letter == x[0])) .WhereNotNull() - .ToArray(); + .ToList(); } internal IReadOnlyList FromEntityPermission(EntityPermission entityPermission) { + var actions = this.ToArray(); // no worry: internally, it's already an array return entityPermission.AssignedPermissions .Where(x => x.Length == 1) - .Select(x => x.ToCharArray()[0]) - .SelectMany(c => this.Where(x => x.Letter == c)) - .Where(action => action != null) + .SelectMany(x => actions.Where(y => y.Letter == x[0])) + .WhereNotNull() .ToList(); } } diff --git a/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs b/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs index 6002c8d2b0..079705645d 100644 --- a/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs +++ b/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using LightInject; using Umbraco.Core.Composing; - namespace Umbraco.Web.Actions { internal class ActionCollectionBuilder : LazyCollectionBuilderBase @@ -19,13 +17,13 @@ namespace Umbraco.Web.Actions protected override IEnumerable CreateItems(params object[] args) { var items = base.CreateItems(args).ToList(); + //validate the items, no actions should exist that do not either expose notifications or permissions - var invalid = items.Where(x => !x.CanBePermissionAssigned && !x.ShowInNotifier).ToList(); - if (invalid.Count > 0) - { - throw new InvalidOperationException($"Invalid actions '{string.Join(", ", invalid.Select(x => x.Alias))}'. All {typeof(IAction)} implementations must be true for either {nameof(IAction.CanBePermissionAssigned)} or {nameof(IAction.ShowInNotifier)}"); - } - return items; + var invalidItems = items.Where(x => !x.CanBePermissionAssigned && !x.ShowInNotifier).ToList(); + if (invalidItems.Count == 0) return items; + + var invalidActions = string.Join(", ", invalidItems.Select(x => "'" + x.Alias + "'")); + throw new InvalidOperationException($"Invalid actions {invalidActions}'. All {typeof(IAction)} implementations must be true for either {nameof(IAction.CanBePermissionAssigned)} or {nameof(IAction.ShowInNotifier)}."); } } } diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs index 1af24db636..2027cb857d 100644 --- a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs +++ b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs @@ -181,7 +181,7 @@ namespace Umbraco.Web.Runtime .Append(); composition.Container.RegisterSingleton(); - + composition.Container.RegisterSingleton(); // register *all* checks, except those marked [HideFromTypeFinder] of course