Few more NRT tweaks (#12323)

* Amended GetAll() on IDataTypeService to return an empty collection rather than null.

* Added a ClearSessionValue method to ISessionManager (given you can no longer set a value to null).

* Allow for null values in a StatefulNotification.

* Removed obsoletion of synchronous messages on TreeControllerBase.

* Fixed further CS8620 warnings in core project.

* Further fix to nullable warning.

* Aligned nullablility of retreiving tree nodes and menus, synchronously or asynchronously (such that we no longer can get null values, always empty collection objects).
This commit is contained in:
Andy Butland
2022-05-01 08:18:09 +02:00
committed by GitHub
parent d47ae6868b
commit 96d33201aa
31 changed files with 102 additions and 77 deletions

View File

@@ -424,8 +424,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[Authorize(Policy = AuthorizationPolicies.SectionAccessForDataTypeReading)]
public IEnumerable<DataTypeBasic>? GetAll()
{
return _dataTypeService?
.GetAll()?
return _dataTypeService
.GetAll()
.Select(_umbracoMapper.Map<IDataType, DataTypeBasic>).WhereNotNull().Where(x => x.IsSystemDataType == false);
}
@@ -439,8 +439,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[Authorize(Policy = AuthorizationPolicies.SectionAccessForDataTypeReading)]
public IDictionary<string, IEnumerable<DataTypeBasic>>? GetGroupedDataTypes()
{
var dataTypes = _dataTypeService?
.GetAll()?
var dataTypes = _dataTypeService
.GetAll()
.Select(_umbracoMapper.Map<IDataType, DataTypeBasic>)
.ToArray();

View File

@@ -73,7 +73,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
return root;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();

View File

@@ -187,7 +187,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
/// </summary>
protected abstract int[] UserStartNodes { get; }
protected virtual ActionResult<TreeNodeCollection?> PerformGetTreeNodes(string id, FormCollection queryStrings)
protected virtual ActionResult<TreeNodeCollection> PerformGetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();
@@ -345,7 +345,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
/// <remarks>
/// This method is overwritten strictly to render the recycle bin, it should serve no other purpose
/// </remarks>
protected sealed override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected sealed override ActionResult<TreeNodeCollection> 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<string>("application") + TreeAlias.EnsureStartsWith('/') + "/recyclebin"));
}
return nodes;
return nodes ?? new TreeNodeCollection();
}
return GetTreeNodesInternal(id, queryStrings);
@@ -435,7 +435,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
/// <remarks>
/// 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.
/// </remarks>
private ActionResult<TreeNodeCollection?> GetTreeNodesInternal(string id, FormCollection queryStrings)
private ActionResult<TreeNodeCollection> GetTreeNodesInternal(string id, FormCollection queryStrings)
{
var current = GetEntityFromId(id);

View File

@@ -58,7 +58,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
return root;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId))
{

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
_dataTypeService = dataTypeService;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> 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<IDataType>(), dt => dt.Id);
var dataTypes = Enumerable.ToDictionary(_dataTypeService.GetAll(children.Select(c => c.Id).ToArray()), dt => dt.Id);
nodes.AddRange(
children

View File

@@ -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.
/// </remarks>
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId))
{

View File

@@ -49,7 +49,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
treeNode.AdditionalData["jsClickCallback"] = "javascript:void(0);";
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.RootString
? WebUtility.UrlDecode(id).TrimStart("/")

View File

@@ -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<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> 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<MenuItemCollection>? GetMenuForNode(string id, FormCollection queryStrings)
protected override ActionResult<MenuItemCollection> 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();
}
/// <summary>

View File

@@ -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<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> 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<MenuItemCollection>? GetMenuForNode(string id, FormCollection queryStrings)
protected override ActionResult<MenuItemCollection> 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();
}
/// <summary>

View File

@@ -48,7 +48,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
return root;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();

View File

@@ -40,7 +40,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
_entityService = entityService;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId))
{

View File

@@ -104,7 +104,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
return node;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();

View File

@@ -52,7 +52,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
{
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();

View File

@@ -56,7 +56,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
//full screen app without tree nodes
return TreeNodeCollection.Empty;

View File

@@ -63,7 +63,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
return menu;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();

View File

@@ -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<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> 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<MenuItemCollection>? GetMenuForNode(string id, FormCollection queryStrings) => null;
protected override ActionResult<MenuItemCollection> GetMenuForNode(string id, FormCollection queryStrings) => _menuItemCollectionFactory.Create();
}
}

View File

@@ -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.
/// </remarks>
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
var nodes = new TreeNodeCollection();

View File

@@ -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.
/// </remarks>
[Obsolete("See GetTreeNodesAsync")]
protected abstract ActionResult<TreeNodeCollection?> GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings);
protected abstract ActionResult<TreeNodeCollection> GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings);
/// <summary>
/// Returns the menu structure for the node
@@ -56,8 +55,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[Obsolete("See GetMenuForNodeAsync")]
protected abstract ActionResult<MenuItemCollection>? GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings);
protected abstract ActionResult<MenuItemCollection> GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings);
/// <summary>
/// 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.
/// </remarks>
protected virtual async Task<ActionResult<TreeNodeCollection?>> GetTreeNodesAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings)
protected virtual async Task<ActionResult<TreeNodeCollection>> GetTreeNodesAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings)
{
return GetTreeNodes(id, queryStrings);
}
@@ -85,7 +83,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
/// <remarks>
/// If overriden, GetMenuForNode will not be called
/// </remarks>
protected virtual async Task<ActionResult<MenuItemCollection>?> GetMenuForNodeAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings)
protected virtual async Task<ActionResult<MenuItemCollection>> GetMenuForNodeAsync(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings)
{
return GetMenuForNode(id, queryStrings);
}

View File

@@ -53,7 +53,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
return root;
}
protected override ActionResult<TreeNodeCollection?> GetTreeNodes(string id, FormCollection queryStrings)
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
//full screen app without tree nodes
return TreeNodeCollection.Empty;