diff --git a/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs b/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs index 43d1d417f0..71b7647b4f 100644 --- a/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs +++ b/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Umbraco.Cms.Core.Collections; diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs index accbbab6e2..5a43295981 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Umbraco.Cms.Core.PropertyEditors; @@ -84,7 +84,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent if (_publishedDataTypes == null) { var dataTypes = _dataTypeService.GetAll(); - _publishedDataTypes = dataTypes?.ToDictionary(x => x.Id, CreatePublishedDataType); + _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); } publishedDataTypes = _publishedDataTypes; @@ -104,7 +104,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent if (_publishedDataTypes == null) { var dataTypes = _dataTypeService.GetAll(); - _publishedDataTypes = dataTypes?.ToDictionary(x => x.Id, CreatePublishedDataType); + _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); } else { @@ -112,11 +112,8 @@ namespace Umbraco.Cms.Core.Models.PublishedContent _publishedDataTypes.Remove(id); var dataTypes = _dataTypeService.GetAll(ids); - if (dataTypes is not null) - { - foreach (var dataType in dataTypes) - _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); - } + foreach (var dataType in dataTypes) + _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); } } } diff --git a/src/Umbraco.Core/Notifications/IStatefulNotification.cs b/src/Umbraco.Core/Notifications/IStatefulNotification.cs index 7fa2382038..c7319524ff 100644 --- a/src/Umbraco.Core/Notifications/IStatefulNotification.cs +++ b/src/Umbraco.Core/Notifications/IStatefulNotification.cs @@ -4,6 +4,6 @@ namespace Umbraco.Cms.Core.Notifications { public interface IStatefulNotification : INotification { - IDictionary State { get; set; } + IDictionary State { get; set; } } } diff --git a/src/Umbraco.Core/Notifications/NotificationExtensions.cs b/src/Umbraco.Core/Notifications/NotificationExtensions.cs index 18ab264cba..d907d3dcfa 100644 --- a/src/Umbraco.Core/Notifications/NotificationExtensions.cs +++ b/src/Umbraco.Core/Notifications/NotificationExtensions.cs @@ -4,7 +4,7 @@ namespace Umbraco.Cms.Core.Notifications { public static class NotificationExtensions { - public static T WithState(this T notification, IDictionary? state) where T : IStatefulNotification + public static T WithState(this T notification, IDictionary? state) where T : IStatefulNotification { notification.State = state!; return notification; diff --git a/src/Umbraco.Core/Notifications/StatefulNotification.cs b/src/Umbraco.Core/Notifications/StatefulNotification.cs index 940e8ac45f..15ee320a40 100644 --- a/src/Umbraco.Core/Notifications/StatefulNotification.cs +++ b/src/Umbraco.Core/Notifications/StatefulNotification.cs @@ -6,15 +6,15 @@ namespace Umbraco.Cms.Core.Notifications { public abstract class StatefulNotification : IStatefulNotification { - private IDictionary? _state; + private IDictionary? _state; /// /// This can be used by event subscribers to store state in the notification so they easily deal with custom state data between /// a starting ("ing") and an ending ("ed") notification /// - public IDictionary State + public IDictionary State { - get => _state ??= new Dictionary(); + get => _state ??= new Dictionary(); set => _state = value; } } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 1b790c9867..e365020ab4 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1377,7 +1377,7 @@ namespace Umbraco.Cms.Core.Services /// private PublishResult CommitDocumentChangesInternal(ICoreScope scope, IContent content, EventMessages eventMessages, IReadOnlyCollection allLangs, - IDictionary? notificationState, + IDictionary? notificationState, int userId = Constants.Security.SuperUserId, bool branchOne = false, bool branchRoot = false) { @@ -3036,7 +3036,7 @@ namespace Umbraco.Cms.Core.Services private PublishResult StrategyCanPublish(ICoreScope scope, IContent content, bool checkPath, IReadOnlyList? culturesPublishing, IReadOnlyCollection? culturesUnpublishing, EventMessages evtMsgs, - IReadOnlyCollection allLangs, IDictionary? notificationState) + IReadOnlyCollection allLangs, IDictionary? notificationState) { // raise Publishing notification if (scope.Notifications.PublishCancelable( diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index c45bc5eade..007b8e8357 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -364,15 +364,11 @@ namespace Umbraco.Cms.Core.Services.Implement /// /// Optional array of Ids /// An enumerable list of objects - public IEnumerable? GetAll(params int[] ids) + public IEnumerable GetAll(params int[] ids) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { var dataTypes = _dataTypeRepository.GetMany(ids); - if (dataTypes is null) - { - return null; - } ConvertMissingEditorsOfDataTypesToLabels(dataTypes); return dataTypes; diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 56766bbe23..4a765ce384 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Core.Services /// /// Optional array of Ids /// An enumerable list of objects - IEnumerable? GetAll(params int[] ids); + IEnumerable GetAll(params int[] ids); /// /// Saves an diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs index 402cc5405b..9d1b9edf9d 100644 --- a/src/Umbraco.Core/Services/MemberService.cs +++ b/src/Umbraco.Core/Services/MemberService.cs @@ -852,7 +852,7 @@ namespace Umbraco.Cms.Core.Services } } - private void DeleteLocked(ICoreScope scope, IMember member, EventMessages evtMsgs, IDictionary? notificationState = null) + private void DeleteLocked(ICoreScope scope, IMember member, EventMessages evtMsgs, IDictionary? notificationState = null) { // a member has no descendants _memberRepository.Delete(member); diff --git a/src/Umbraco.Core/Web/ISessionManager.cs b/src/Umbraco.Core/Web/ISessionManager.cs index bd0cab9cd6..3ba691e222 100644 --- a/src/Umbraco.Core/Web/ISessionManager.cs +++ b/src/Umbraco.Core/Web/ISessionManager.cs @@ -2,7 +2,10 @@ namespace Umbraco.Cms.Core.Web { public interface ISessionManager { - string? GetSessionValue(string sessionName); - void SetSessionValue(string sessionName, string value); + string? GetSessionValue(string key); + + void SetSessionValue(string key, string value); + + void ClearSessionValue(string key); } } diff --git a/src/Umbraco.Infrastructure/Routing/RedirectTrackingHandler.cs b/src/Umbraco.Infrastructure/Routing/RedirectTrackingHandler.cs index dabee6db9d..bd5fc3a573 100644 --- a/src/Umbraco.Infrastructure/Routing/RedirectTrackingHandler.cs +++ b/src/Umbraco.Infrastructure/Routing/RedirectTrackingHandler.cs @@ -90,7 +90,7 @@ namespace Umbraco.Cms.Core.Routing notification.State[NotificationStateKey] = new OldRoutesDictionary(); } - return (OldRoutesDictionary)notification.State[NotificationStateKey]; + return (OldRoutesDictionary?)notification.State[NotificationStateKey] ?? new OldRoutesDictionary(); } private void StoreOldRoute(IContent entity, OldRoutesDictionary oldRoutes) diff --git a/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs index 7c0567b1bb..393d24ca50 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/DataTypeController.cs @@ -424,8 +424,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers [Authorize(Policy = AuthorizationPolicies.SectionAccessForDataTypeReading)] public IEnumerable? GetAll() { - return _dataTypeService? - .GetAll()? + return _dataTypeService + .GetAll() .Select(_umbracoMapper.Map).WhereNotNull().Where(x => x.IsSystemDataType == false); } @@ -439,8 +439,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers [Authorize(Policy = AuthorizationPolicies.SectionAccessForDataTypeReading)] public IDictionary>? GetGroupedDataTypes() { - var dataTypes = _dataTypeService? - .GetAll()? + var dataTypes = _dataTypeService + .GetAll() .Select(_umbracoMapper.Map) .ToArray(); diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs index 173183645b..15f5839f30 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentBlueprintTreeController.cs @@ -73,7 +73,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees return root; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs index 028e318b7a..f0e62f8a66 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs @@ -187,7 +187,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// protected abstract int[] UserStartNodes { get; } - protected virtual ActionResult PerformGetTreeNodes(string id, FormCollection queryStrings) + protected virtual ActionResult PerformGetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); @@ -345,7 +345,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// /// This method is overwritten strictly to render the recycle bin, it should serve no other purpose /// - protected sealed override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected sealed override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { //check if we're rendering the root if (id == Constants.System.RootString && UserStartNodes.Contains(Constants.System.Root)) @@ -384,7 +384,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees queryStrings.GetRequiredValue("application") + TreeAlias.EnsureStartsWith('/') + "/recyclebin")); } - return nodes; + return nodes ?? new TreeNodeCollection(); } return GetTreeNodesInternal(id, queryStrings); @@ -435,7 +435,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// /// Currently this just checks if it is a container type, if it is we cannot render children. In the future this might check for other things. /// - private ActionResult GetTreeNodesInternal(string id, FormCollection queryStrings) + private ActionResult GetTreeNodesInternal(string id, FormCollection queryStrings) { var current = GetEntityFromId(id); diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs index a688713109..f19cee3d0a 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs @@ -58,7 +58,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees return root; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId)) { diff --git a/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs index 408eca9556..8a5a12d50a 100644 --- a/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/DataTypeTreeController.cs @@ -41,7 +41,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees _dataTypeService = dataTypeService; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId)) { @@ -71,7 +71,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees var systemListViewDataTypeIds = GetNonDeletableSystemListViewDataTypeIds(); var children = _entityService.GetChildren(intId, UmbracoObjectTypes.DataType).ToArray(); - var dataTypes = Enumerable.ToDictionary(_dataTypeService.GetAll(children.Select(c => c.Id).ToArray()) ?? Enumerable.Empty(), dt => dt.Id); + var dataTypes = Enumerable.ToDictionary(_dataTypeService.GetAll(children.Select(c => c.Id).ToArray()), dt => dt.Id); nodes.AddRange( children diff --git a/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs index 67a6c892bc..2e97769ca5 100644 --- a/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/DictionaryTreeController.cs @@ -71,7 +71,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// We are allowing an arbitrary number of query strings to be passed in so that developers are able to persist custom data from the front-end /// to the back end to be used in the query for model data. /// - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId)) { diff --git a/src/Umbraco.Web.BackOffice/Trees/FileSystemTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/FileSystemTreeController.cs index 579b1c5f14..ba32715f59 100644 --- a/src/Umbraco.Web.BackOffice/Trees/FileSystemTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/FileSystemTreeController.cs @@ -49,7 +49,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees treeNode.AdditionalData["jsClickCallback"] = "javascript:void(0);"; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var path = string.IsNullOrEmpty(id) == false && id != Constants.System.RootString ? WebUtility.UrlDecode(id).TrimStart("/") diff --git a/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs index aaffe4f823..c763bc1167 100644 --- a/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/LanguageTreeController.cs @@ -17,24 +17,28 @@ namespace Umbraco.Cms.Web.BackOffice.Trees [CoreTree] public class LanguageTreeController : TreeController { + private readonly IMenuItemCollectionFactory _menuItemCollectionFactory; public LanguageTreeController( ILocalizedTextService textService, UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, - IEventAggregator eventAggregator) + IEventAggregator eventAggregator, + IMenuItemCollectionFactory menuItemCollectionFactory) : base(textService, umbracoApiControllerTypeCollection, eventAggregator) { + _menuItemCollectionFactory = menuItemCollectionFactory; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { //We don't have any child nodes & only use the root node to load a custom UI return new TreeNodeCollection(); } - protected override ActionResult? GetMenuForNode(string id, FormCollection queryStrings) + protected override ActionResult GetMenuForNode(string id, FormCollection queryStrings) { //We don't have any menu item options (such as create/delete/reload) & only use the root node to load a custom UI - return null; + return _menuItemCollectionFactory.Create(); } /// diff --git a/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs index 7fbcfb6100..6e3bdd7ee2 100644 --- a/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/LogViewerTreeController.cs @@ -17,24 +17,28 @@ namespace Umbraco.Cms.Web.BackOffice.Trees [CoreTree] public class LogViewerTreeController : TreeController { + private readonly IMenuItemCollectionFactory _menuItemCollectionFactory; + public LogViewerTreeController( ILocalizedTextService localizedTextService, UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, - IEventAggregator eventAggregator) + IEventAggregator eventAggregator, + IMenuItemCollectionFactory menuItemCollectionFactory) : base(localizedTextService, umbracoApiControllerTypeCollection, eventAggregator) { + _menuItemCollectionFactory = menuItemCollectionFactory; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { //We don't have any child nodes & only use the root node to load a custom UI return new TreeNodeCollection(); } - protected override ActionResult? GetMenuForNode(string id, FormCollection queryStrings) + protected override ActionResult GetMenuForNode(string id, FormCollection queryStrings) { //We don't have any menu item options (such as create/delete/reload) & only use the root node to load a custom UI - return null; + return _menuItemCollectionFactory.Create(); } /// diff --git a/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs index 310d961bb7..4edff226f6 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MacrosTreeController.cs @@ -48,7 +48,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees return root; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); diff --git a/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs index de46d135a3..af5eaabeef 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MediaTypeTreeController.cs @@ -40,7 +40,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees _entityService = entityService; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId)) { diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs index 4b997b44de..736b5af9b2 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTreeController.cs @@ -104,7 +104,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees return node; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); diff --git a/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs index 975ac23bbc..64e8081dec 100644 --- a/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/MemberTypeAndGroupTreeControllerBase.cs @@ -52,7 +52,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees { } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); diff --git a/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs index 7075258559..f9b0adca15 100644 --- a/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/PackagesTreeController.cs @@ -56,7 +56,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { //full screen app without tree nodes return TreeNodeCollection.Empty; diff --git a/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs index 5178253667..22f96fa7c8 100644 --- a/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/RelationTypeTreeController.cs @@ -63,7 +63,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees return menu; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); diff --git a/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs index d1524970fd..55b67f18fe 100644 --- a/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/StaticFilesTreeController.cs @@ -16,18 +16,24 @@ namespace Umbraco.Cms.Web.BackOffice.Trees public class StaticFilesTreeController : TreeController { private readonly IFileSystem _fileSystem; + private readonly IMenuItemCollectionFactory _menuItemCollectionFactory; + private const string AppPlugins = "App_Plugins"; private const string Webroot = "wwwroot"; - public StaticFilesTreeController(ILocalizedTextService localizedTextService, - UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, IEventAggregator eventAggregator, - IPhysicalFileSystem fileSystem) : - base(localizedTextService, umbracoApiControllerTypeCollection, eventAggregator) + public StaticFilesTreeController( + ILocalizedTextService localizedTextService, + UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, + IEventAggregator eventAggregator, + IPhysicalFileSystem fileSystem, + IMenuItemCollectionFactory menuItemCollectionFactory) + : base(localizedTextService, umbracoApiControllerTypeCollection, eventAggregator) { _fileSystem = fileSystem; + _menuItemCollectionFactory = menuItemCollectionFactory; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var path = string.IsNullOrEmpty(id) == false && id != Constants.System.RootString ? WebUtility.UrlDecode(id).TrimStart("/") @@ -73,6 +79,6 @@ namespace Umbraco.Cms.Web.BackOffice.Trees } // We don't have any menu item options (such as create/delete/reload) & only use the root node to load a custom UI - protected override ActionResult? GetMenuForNode(string id, FormCollection queryStrings) => null; + protected override ActionResult GetMenuForNode(string id, FormCollection queryStrings) => _menuItemCollectionFactory.Create(); } } diff --git a/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs index a155493aff..1c4a5b5030 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TemplatesTreeController.cs @@ -74,7 +74,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// We are allowing an arbitrary number of query strings to be pased in so that developers are able to persist custom data from the front-end /// to the back end to be used in the query for model data. /// - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { var nodes = new TreeNodeCollection(); diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs index a1b9da0a56..fb30d7c147 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs @@ -47,8 +47,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// We are allowing an arbitrary number of query strings to be passed in so that developers are able to persist custom data from the front-end /// to the back end to be used in the query for model data. /// - [Obsolete("See GetTreeNodesAsync")] - protected abstract ActionResult GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings); + protected abstract ActionResult GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings); /// /// Returns the menu structure for the node @@ -56,8 +55,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// /// /// - [Obsolete("See GetMenuForNodeAsync")] - protected abstract ActionResult? GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings); + protected abstract ActionResult GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings); /// /// The method called to render the contents of the tree structure @@ -71,7 +69,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// We are allowing an arbitrary number of query strings to be passed in so that developers are able to persist custom data from the front-end /// to the back end to be used in the query for model data. /// - protected virtual async Task> GetTreeNodesAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings) + protected virtual async Task> GetTreeNodesAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings) { return GetTreeNodes(id, queryStrings); } @@ -85,7 +83,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees /// /// If overriden, GetMenuForNode will not be called /// - protected virtual async Task?> GetMenuForNodeAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings) + protected virtual async Task> GetMenuForNodeAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings) { return GetMenuForNode(id, queryStrings); } diff --git a/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs index c7d8b29955..823f9b0c04 100644 --- a/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/UserTreeController.cs @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees return root; } - protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) + protected override ActionResult GetTreeNodes(string id, FormCollection queryStrings) { //full screen app without tree nodes return TreeNodeCollection.Empty; diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs index a4d4e53a60..5f71e0c02a 100644 --- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs +++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreSessionManager.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Umbraco.Cms.Core.Net; using Umbraco.Cms.Core.Web; @@ -14,7 +14,6 @@ namespace Umbraco.Cms.Web.Common.AspNetCore _httpContextAccessor = httpContextAccessor; } - /// /// If session isn't enabled this will throw an exception so we check /// @@ -24,7 +23,7 @@ namespace Umbraco.Cms.Web.Common.AspNetCore { get { - var httpContext = _httpContextAccessor?.HttpContext; + HttpContext? httpContext = _httpContextAccessor?.HttpContext; return IsSessionsAvailable ? httpContext?.Session?.Id @@ -32,17 +31,35 @@ namespace Umbraco.Cms.Web.Common.AspNetCore } } - public string? GetSessionValue(string sessionName) + public string? GetSessionValue(string key) { - if(!IsSessionsAvailable) return null; - return _httpContextAccessor.HttpContext?.Session.GetString(sessionName); + if (!IsSessionsAvailable) + { + return null; + } + + return _httpContextAccessor.HttpContext?.Session.GetString(key); } - public void SetSessionValue(string sessionName, string value) + public void SetSessionValue(string key, string value) { - if(!IsSessionsAvailable) return; - _httpContextAccessor.HttpContext?.Session.SetString(sessionName, value); + if (!IsSessionsAvailable) + { + return; + } + + _httpContextAccessor.HttpContext?.Session.SetString(key, value); + } + + public void ClearSessionValue(string key) + { + if (!IsSessionsAvailable) + { + return; + } + + _httpContextAccessor.HttpContext?.Session.Remove(key); } } }