From 5abd734a58dc98b76b3af33da9aa109f1ccd84b3 Mon Sep 17 00:00:00 2001 From: Chad Currie Date: Fri, 18 Feb 2022 00:45:27 +1300 Subject: [PATCH 1/5] Relax casting for tree controller to allow for other implementations --- src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs index db714bb675b2..a3ad92c10934 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs @@ -349,7 +349,7 @@ private async Task> GetApiControllerProxy(Type controllerTy var actionContext = new ActionContext(HttpContext, routeData, actionDescriptor); var proxyControllerContext = new ControllerContext(actionContext); - var controller = (TreeController)_controllerFactory.CreateController(proxyControllerContext); + var controller = (UmbracoAuthorizedApiController)_controllerFactory.CreateController(proxyControllerContext); // TODO: What about other filters? Will they execute? var isAllowed = await controller.ControllerContext.InvokeAuthorizationFiltersForRequest(actionContext); From 4f30308e05ce6bb6f6459e615f5a165baf380317 Mon Sep 17 00:00:00 2001 From: Chad Currie Date: Fri, 18 Feb 2022 00:55:43 +1300 Subject: [PATCH 2/5] async support --- .../Trees/ApplicationTreeController.cs | 2 +- .../Trees/TreeControllerBase.cs | 35 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs index a3ad92c10934..ee7d4807318d 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ApplicationTreeController.cs @@ -349,7 +349,7 @@ private async Task> GetApiControllerProxy(Type controllerTy var actionContext = new ActionContext(HttpContext, routeData, actionDescriptor); var proxyControllerContext = new ControllerContext(actionContext); - var controller = (UmbracoAuthorizedApiController)_controllerFactory.CreateController(proxyControllerContext); + var controller = (TreeControllerBase)_controllerFactory.CreateController(proxyControllerContext); // TODO: What about other filters? Will they execute? var isAllowed = await controller.ControllerContext.InvokeAuthorizationFiltersForRequest(actionContext); diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs index b6f294896526..d94c69fb30bd 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs @@ -57,6 +57,37 @@ protected TreeControllerBase(UmbracoApiControllerTypeCollection apiControllers, /// protected abstract ActionResult GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings); + /// + /// The method called to render the contents of the tree structure + /// + /// + /// + /// All of the query string parameters passed from jsTree + /// + /// + /// If overriden, GetTreeNodes will not be called + /// 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) + { + return GetTreeNodes(id, queryStrings); + } + + /// + /// Returns the menu structure for the node + /// + /// + /// + /// + /// + /// If overriden, GetMenuForNode will not be called + /// + protected virtual async Task> GetMenuForNodeAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings) + { + return GetMenuForNode(id, queryStrings); + } + /// /// The name to display on the root node /// @@ -132,7 +163,7 @@ public async Task> GetRootNode([ModelBinder(typeof(HttpQu public async Task> GetNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings) { if (queryStrings == null) queryStrings = FormCollection.Empty; - var nodesResult = GetTreeNodes(id, queryStrings); + var nodesResult = await GetTreeNodesAsync(id, queryStrings); if (!(nodesResult.Result is null)) { @@ -164,7 +195,7 @@ public async Task> GetNodes(string id, [ModelBi public async Task> GetMenu(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings) { if (queryStrings == null) queryStrings = FormCollection.Empty; - var menuResult = GetMenuForNode(id, queryStrings); + var menuResult = await GetMenuForNodeAsync(id, queryStrings); if (!(menuResult.Result is null)) { return menuResult.Result; From 41f50ba7dde63231b9900ef33aead85416b5f9d5 Mon Sep 17 00:00:00 2001 From: Chad Currie Date: Fri, 18 Feb 2022 01:06:44 +1300 Subject: [PATCH 3/5] Add id to TreeNodesRenderingNotification --- src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs | 2 +- .../Trees/TreeNodesRenderingNotification.cs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs index d94c69fb30bd..02ecc5d14beb 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs @@ -181,7 +181,7 @@ public async Task> GetNodes(string id, [ModelBi node.RoutePath = "#"; //raise the event - await _eventAggregator.PublishAsync(new TreeNodesRenderingNotification(nodes, queryStrings, TreeAlias)); + await _eventAggregator.PublishAsync(new TreeNodesRenderingNotification(nodes, queryStrings, TreeAlias, id)); return nodes; } diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs b/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs index f022b23a2056..280041b0cc5a 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs @@ -26,11 +26,17 @@ public class TreeNodesRenderingNotification : INotification /// public string TreeAlias { get; } - public TreeNodesRenderingNotification(TreeNodeCollection nodes, FormCollection queryString, string treeAlias) + /// + /// Gets id of the node rendered + /// + public string Id { get; } + + public TreeNodesRenderingNotification(TreeNodeCollection nodes, FormCollection queryString, string treeAlias, string id) { Nodes = nodes; QueryString = queryString; TreeAlias = treeAlias; + Id = id; } } } From d5d036475b36c3bf8d7f406a9fbe493ff3e515d1 Mon Sep 17 00:00:00 2001 From: Chad Currie Date: Tue, 22 Feb 2022 22:10:45 +1300 Subject: [PATCH 4/5] Include obsolete constructor. Fix stylecop warnings --- .../Trees/TreeNodesRenderingNotification.cs | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs b/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs index 280041b0cc5a..b7334c0e5ba2 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeNodesRenderingNotification.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.AspNetCore.Http; using Umbraco.Cms.Core.Trees; @@ -11,32 +12,57 @@ namespace Umbraco.Cms.Core.Notifications /// public class TreeNodesRenderingNotification : INotification { + + /// + /// Initializes a new instance of the class. + /// + /// The tree nodes being rendered + /// The query string of the current request + /// The alias of the tree rendered + /// The id of the node rendered + public TreeNodesRenderingNotification(TreeNodeCollection nodes, FormCollection queryString, string treeAlias, string id) + { + Nodes = nodes; + QueryString = queryString; + TreeAlias = treeAlias; + Id = id; + } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// The tree nodes being rendered + /// The query string of the current request + /// The alias of the tree rendered + [Obsolete("Use ctor with all parameters")] + public TreeNodesRenderingNotification(TreeNodeCollection nodes, FormCollection queryString, string treeAlias) + { + Nodes = nodes; + QueryString = queryString; + TreeAlias = treeAlias; + Id = default; + } + /// - /// The tree nodes being rendered + /// Gets the tree nodes being rendered /// public TreeNodeCollection Nodes { get; } /// - /// The query string of the current request + /// Gets the query string of the current request /// public FormCollection QueryString { get; } /// - /// The alias of the tree rendered + /// Gets the alias of the tree rendered /// public string TreeAlias { get; } /// - /// Gets id of the node rendered + /// Gets the id of the node rendered /// public string Id { get; } - public TreeNodesRenderingNotification(TreeNodeCollection nodes, FormCollection queryString, string treeAlias, string id) - { - Nodes = nodes; - QueryString = queryString; - TreeAlias = treeAlias; - Id = id; - } } } From dc21821d3663c787bda4b47e285462556151c12d Mon Sep 17 00:00:00 2001 From: Chad Currie Date: Tue, 22 Feb 2022 22:18:54 +1300 Subject: [PATCH 5/5] Add obsolete --- src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs index 02ecc5d14beb..20d0e1a305c1 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeControllerBase.cs @@ -47,6 +47,7 @@ protected TreeControllerBase(UmbracoApiControllerTypeCollection apiControllers, /// 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); /// @@ -55,6 +56,7 @@ protected TreeControllerBase(UmbracoApiControllerTypeCollection apiControllers, /// /// /// + [Obsolete("See GetMenuForNodeAsync")] protected abstract ActionResult GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings); ///