From b1ece9b2023a19565e191edcd8e51818cbc15183 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 4 May 2022 19:01:54 +0200 Subject: [PATCH 1/5] NRT amends necessary for Deploy (#12357) * Allowed null item retrievel in IDeployContext. * Allowed null item retrievel in IImageSourceParser. * Allowed null item retrievel in IMacroParser. * Set null syntax for other Deploy interfaces. (cherry picked from commit a42ff2c2677aac437bcefb7f8304775b4a32d07b) --- src/Umbraco.Core/Deploy/IDeployContext.cs | 4 ++-- src/Umbraco.Core/Deploy/IImageSourceParser.cs | 6 ++---- src/Umbraco.Core/Deploy/IMacroParser.cs | 6 +++--- src/Umbraco.Core/Deploy/IServiceConnector.cs | 4 ++-- src/Umbraco.Core/Deploy/IValueConnector.cs | 6 +++--- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Core/Deploy/IDeployContext.cs b/src/Umbraco.Core/Deploy/IDeployContext.cs index c2a3a39d1e..c6e2da997b 100644 --- a/src/Umbraco.Core/Deploy/IDeployContext.cs +++ b/src/Umbraco.Core/Deploy/IDeployContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Umbraco.Cms.Core.Deploy @@ -37,7 +37,7 @@ namespace Umbraco.Cms.Core.Deploy /// The type of the item. /// The key of the item. /// The item with the specified key and type, if any, else null. - T Item(string key) where T : class; + T? Item(string key) where T : class; ///// ///// Gets the global deployment cancellation token. diff --git a/src/Umbraco.Core/Deploy/IImageSourceParser.cs b/src/Umbraco.Core/Deploy/IImageSourceParser.cs index a15b45f40b..084ba1b118 100644 --- a/src/Umbraco.Core/Deploy/IImageSourceParser.cs +++ b/src/Umbraco.Core/Deploy/IImageSourceParser.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; - namespace Umbraco.Cms.Core.Deploy { /// @@ -14,7 +12,7 @@ namespace Umbraco.Cms.Core.Deploy /// A list of dependencies. /// The parsed value. /// Turns src="/media/..." into src="umb://media/..." and adds the corresponding udi to the dependencies. - string ToArtifact(string value, ICollection dependencies); + string? ToArtifact(string? value, ICollection dependencies); /// /// Parses an artifact property value and produces an Umbraco property value. @@ -22,6 +20,6 @@ namespace Umbraco.Cms.Core.Deploy /// The artifact property value. /// The parsed value. /// Turns umb://media/... into /media/.... - string FromArtifact(string value); + string? FromArtifact(string? value); } } diff --git a/src/Umbraco.Core/Deploy/IMacroParser.cs b/src/Umbraco.Core/Deploy/IMacroParser.cs index 622a4abc1b..81b014c1cc 100644 --- a/src/Umbraco.Core/Deploy/IMacroParser.cs +++ b/src/Umbraco.Core/Deploy/IMacroParser.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Umbraco.Cms.Core.Deploy { @@ -10,14 +10,14 @@ namespace Umbraco.Cms.Core.Deploy /// Property value. /// A list of dependencies. /// Parsed value. - string ToArtifact(string value, ICollection dependencies); + string? ToArtifact(string? value, ICollection dependencies); /// /// Parses an artifact property value and produces an Umbraco property value. /// /// Artifact property value. /// Parsed value. - string FromArtifact(string value); + string? FromArtifact(string? value); /// /// Tries to replace the value of the attribute/parameter with a value containing a converted identifier. diff --git a/src/Umbraco.Core/Deploy/IServiceConnector.cs b/src/Umbraco.Core/Deploy/IServiceConnector.cs index b28989f5de..dfc4f3d28e 100644 --- a/src/Umbraco.Core/Deploy/IServiceConnector.cs +++ b/src/Umbraco.Core/Deploy/IServiceConnector.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Cms.Core.Composing; namespace Umbraco.Cms.Core.Deploy @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.Deploy /// /// The entity identifier of the artifact. /// The corresponding artifact, or null. - IArtifact GetArtifact(Udi udi); + IArtifact? GetArtifact(Udi udi); /// /// Gets an artifact. diff --git a/src/Umbraco.Core/Deploy/IValueConnector.cs b/src/Umbraco.Core/Deploy/IValueConnector.cs index b7ba2e4096..32a536a870 100644 --- a/src/Umbraco.Core/Deploy/IValueConnector.cs +++ b/src/Umbraco.Core/Deploy/IValueConnector.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Deploy @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Deploy /// The value property type /// The content dependencies. /// The deploy property value. - string ToArtifact(object value, IPropertyType propertyType, ICollection dependencies); + string? ToArtifact(object? value, IPropertyType propertyType, ICollection dependencies); /// /// Gets the content property value corresponding to a deploy property value. @@ -32,6 +32,6 @@ namespace Umbraco.Cms.Core.Deploy /// The value property type< /// The current content property value. /// The content property value. - object FromArtifact(string value, IPropertyType propertyType, object currentValue); + object? FromArtifact(string? value, IPropertyType propertyType, object currentValue); } } From fbdf704567c98d375102812fd92985a504962907 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 4 May 2022 19:05:10 +0200 Subject: [PATCH 2/5] Further amends to NRT definitions (#12356) * Ensured all GetContainers methods in IDataTypeService return non-nullable collections. * Further amends to ensure services return non-nullable collections. * Aligned nullability of IMediaService.GetMediaFileContentStream(string * Removed return of nullable streams from IFileService. * Fixed nullability mismatch. (cherry picked from commit 735086a7470457f37350ab4118151e907e7bda77) --- .../Persistence/IQueryRepository.cs | 4 +- src/Umbraco.Core/Services/AuditService.cs | 2 +- src/Umbraco.Core/Services/ConsentService.cs | 2 +- src/Umbraco.Core/Services/ContentService.cs | 50 ++++++++++--------- ...peServiceBaseOfTRepositoryTItemTService.cs | 6 +-- src/Umbraco.Core/Services/DataTypeService.cs | 12 ++--- .../Services/EntityXmlSerializer.cs | 9 ++-- .../Services/ExternalLoginService.cs | 16 +++--- src/Umbraco.Core/Services/FileService.cs | 16 +++--- src/Umbraco.Core/Services/IAuditService.cs | 4 +- src/Umbraco.Core/Services/IConsentService.cs | 4 +- src/Umbraco.Core/Services/IContentService.cs | 10 ++-- .../Services/IContentTypeServiceBase.cs | 6 +-- src/Umbraco.Core/Services/IDataTypeService.cs | 6 +-- .../Services/IExternalLoginService.cs | 6 +-- .../Services/IExternalLoginWithKeyService.cs | 6 +-- src/Umbraco.Core/Services/IFileService.cs | 10 ++-- src/Umbraco.Core/Services/IMediaService.cs | 2 +- .../Security/BackOfficeUserStore.cs | 4 +- .../Security/MemberUserStore.cs | 4 +- 20 files changed, 85 insertions(+), 94 deletions(-) diff --git a/src/Umbraco.Core/Persistence/IQueryRepository.cs b/src/Umbraco.Core/Persistence/IQueryRepository.cs index 6623fbf0fc..1a8dbaf971 100644 --- a/src/Umbraco.Core/Persistence/IQueryRepository.cs +++ b/src/Umbraco.Core/Persistence/IQueryRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Cms.Core.Persistence.Querying; namespace Umbraco.Cms.Core.Persistence @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Persistence /// /// Gets entities. /// - IEnumerable? Get(IQuery query); + IEnumerable Get(IQuery query); /// /// Counts entities. diff --git a/src/Umbraco.Core/Services/AuditService.cs b/src/Umbraco.Core/Services/AuditService.cs index e9a35f80ba..f7560afa93 100644 --- a/src/Umbraco.Core/Services/AuditService.cs +++ b/src/Umbraco.Core/Services/AuditService.cs @@ -34,7 +34,7 @@ namespace Umbraco.Cms.Core.Services.Implement } } - public IEnumerable? GetLogs(int objectId) + public IEnumerable GetLogs(int objectId) { using (var scope = ScopeProvider.CreateCoreScope()) { diff --git a/src/Umbraco.Core/Services/ConsentService.cs b/src/Umbraco.Core/Services/ConsentService.cs index 9a767d9c4e..d37e2e4d0f 100644 --- a/src/Umbraco.Core/Services/ConsentService.cs +++ b/src/Umbraco.Core/Services/ConsentService.cs @@ -57,7 +57,7 @@ namespace Umbraco.Cms.Core.Services } /// - public IEnumerable? LookupConsent(string? source = null, string? context = null, string? action = null, + public IEnumerable LookupConsent(string? source = null, string? context = null, string? action = null, bool sourceStartsWith = false, bool contextStartsWith = false, bool actionStartsWith = false, bool includeHistory = false) { diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index e365020ab4..a2fa13a346 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -513,7 +513,7 @@ namespace Umbraco.Cms.Core.Services /// /// /// - public IEnumerable? GetByIds(IEnumerable ids) + public IEnumerable GetByIds(IEnumerable ids) { Guid[] idsA = ids.ToArray(); if (idsA.Length == 0) @@ -533,7 +533,7 @@ namespace Umbraco.Cms.Core.Services return idsA.Select(x => index.TryGetValue(x, out IContent? c) ? c : null).WhereNotNull(); } - return null; + return Enumerable.Empty(); } } @@ -600,7 +600,7 @@ namespace Umbraco.Cms.Core.Services /// The level to retrieve Content from /// An Enumerable list of objects /// Contrary to most methods, this method filters out trashed content items. - public IEnumerable? GetByLevel(int level) + public IEnumerable GetByLevel(int level) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -670,10 +670,15 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the to retrieve ancestors for /// An Enumerable list of objects - public IEnumerable? GetAncestors(int id) + public IEnumerable GetAncestors(int id) { // intentionally not locking IContent? content = GetById(id); + if (content is null) + { + return Enumerable.Empty(); + } + return GetAncestors(content); } @@ -682,10 +687,10 @@ namespace Umbraco.Cms.Core.Services /// /// to retrieve ancestors for /// An Enumerable list of objects - public IEnumerable? GetAncestors(IContent? content) + public IEnumerable GetAncestors(IContent content) { //null check otherwise we get exceptions - if (content?.Path.IsNullOrWhiteSpace() ?? true) + if (content.Path.IsNullOrWhiteSpace()) { return Enumerable.Empty(); } @@ -708,13 +713,13 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the Parent to retrieve Children from /// An Enumerable list of published objects - public IEnumerable? GetPublishedChildren(int id) + public IEnumerable GetPublishedChildren(int id) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { scope.ReadLock(Constants.Locks.ContentTree); IQuery? query = Query().Where(x => x.ParentId == id && x.Published); - return _documentRepository.Get(query)?.OrderBy(x => x.SortOrder); + return _documentRepository.Get(query).OrderBy(x => x.SortOrder); } } @@ -849,7 +854,7 @@ namespace Umbraco.Cms.Core.Services { scope.ReadLock(Constants.Locks.ContentTree); IQuery query = Query().Where(x => x.ParentId == Constants.System.Root); - return _documentRepository.Get(query) ?? Enumerable.Empty(); + return _documentRepository.Get(query); } } @@ -857,7 +862,7 @@ namespace Umbraco.Cms.Core.Services /// Gets all published content items /// /// - internal IEnumerable? GetAllPublished() + internal IEnumerable GetAllPublished() { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -2559,7 +2564,7 @@ namespace Umbraco.Cms.Core.Services // emptying the recycle bin means deleting whatever is in there - do it properly! IQuery? query = Query().Where(x => x.ParentId == Constants.System.RecycleBinContent); - IContent[]? contents = _documentRepository.Get(query)?.ToArray(); + IContent[] contents = _documentRepository.Get(query).ToArray(); var emptyingRecycleBinNotification = new ContentEmptyingRecycleBinNotification(contents, eventMessages); if (scope.Notifications.PublishCancelable(emptyingRecycleBinNotification)) @@ -2982,7 +2987,7 @@ namespace Umbraco.Cms.Core.Services var pathMatch = content.Path + ","; IQuery query = Query() .Where(x => x.Id != content.Id && x.Path.StartsWith(pathMatch) /*&& x.Trashed == false*/); - IEnumerable? contents = _documentRepository.Get(query); + IEnumerable contents = _documentRepository.Get(query); // beware! contents contains all published version below content // including those that are not directly published because below an unpublished content @@ -3355,7 +3360,7 @@ namespace Umbraco.Cms.Core.Services scope.WriteLock(Constants.Locks.ContentTree); IQuery query = Query().WhereIn(x => x.ContentTypeId, contentTypeIdsA); - IContent[]? contents = _documentRepository.Get(query)?.ToArray(); + IContent[] contents = _documentRepository.Get(query).ToArray(); if (contents is null) { @@ -3383,15 +3388,12 @@ namespace Umbraco.Cms.Core.Services // if current content has children, move them to trash IContent c = content; IQuery childQuery = Query().Where(x => x.ParentId == c.Id); - IEnumerable? children = _documentRepository.Get(childQuery); - if (children is not null) + IEnumerable children = _documentRepository.Get(childQuery); + foreach (IContent child in children) { - foreach (IContent child in children) - { - // see MoveToRecycleBin - PerformMoveLocked(child, Constants.System.RecycleBinContent, null, userId, moves, true); - changes.Add(new TreeChange(content, TreeChangeTypes.RefreshBranch)); - } + // see MoveToRecycleBin + PerformMoveLocked(child, Constants.System.RecycleBinContent, null, userId, moves, true); + changes.Add(new TreeChange(content, TreeChangeTypes.RefreshBranch)); } // delete content @@ -3442,7 +3444,7 @@ namespace Umbraco.Cms.Core.Services scope.ReadLock(Constants.Locks.ContentTypes); IQuery query = Query().Where(x => x.Alias == contentTypeAlias); - IContentType? contentType = _contentTypeRepository.Get(query)?.FirstOrDefault(); + IContentType? contentType = _contentTypeRepository.Get(query).FirstOrDefault(); if (contentType == null) { @@ -3604,7 +3606,7 @@ namespace Umbraco.Cms.Core.Services return content; } - public IEnumerable? GetBlueprintsForContentTypes(params int[] contentTypeId) + public IEnumerable GetBlueprintsForContentTypes(params int[] contentTypeId) { using (ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -3614,7 +3616,7 @@ namespace Umbraco.Cms.Core.Services query.Where(x => contentTypeId.Contains(x.ContentTypeId)); } - return _documentBlueprintRepository.Get(query)?.Select(x => + return _documentBlueprintRepository.Get(query).Select(x => { x.Blueprint = true; return x; diff --git a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs index 7eb87b28a9..10775e2ce3 100644 --- a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs +++ b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs @@ -312,7 +312,7 @@ namespace Umbraco.Cms.Core.Services } } - public IEnumerable? GetChildren(int id) + public IEnumerable GetChildren(int id) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -322,7 +322,7 @@ namespace Umbraco.Cms.Core.Services } } - public IEnumerable? GetChildren(Guid id) + public IEnumerable GetChildren(Guid id) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -403,7 +403,7 @@ namespace Umbraco.Cms.Core.Services { var i = ids.Pop(); var query = Query().Where(x => x.ParentId == i); - var result = Repository.Get(query)?.ToArray(); + var result = Repository.Get(query).ToArray(); if (result is not null) { diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index 007b8e8357..5c9d5847ed 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -164,7 +164,7 @@ namespace Umbraco.Cms.Core.Services.Implement } } - public IEnumerable? GetContainers(IDataType dataType) + public IEnumerable GetContainers(IDataType dataType) { var ancestorIds = dataType.Path.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries) .Select(x => @@ -178,7 +178,7 @@ namespace Umbraco.Cms.Core.Services.Implement return GetContainers(ancestorIds); } - public IEnumerable? GetContainers(int[] containerIds) + public IEnumerable GetContainers(int[] containerIds) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -333,7 +333,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { var query = Query().Where(x => x.Key == id); - var dataType = _dataTypeRepository.Get(query)?.FirstOrDefault(); + var dataType = _dataTypeRepository.Get(query).FirstOrDefault(); ConvertMissingEditorOfDataTypeToLabel(dataType); return dataType; } @@ -344,16 +344,12 @@ namespace Umbraco.Cms.Core.Services.Implement /// /// Alias of the property editor /// Collection of objects with a matching control id - public IEnumerable? GetByEditorAlias(string propertyEditorAlias) + public IEnumerable GetByEditorAlias(string propertyEditorAlias) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { var query = Query().Where(x => x.EditorAlias == propertyEditorAlias); var dataType = _dataTypeRepository.Get(query); - if (dataType is null) - { - return null; - } ConvertMissingEditorsOfDataTypesToLabels(dataType); return dataType; } diff --git a/src/Umbraco.Core/Services/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/EntityXmlSerializer.cs index a5500ac690..8123dd06da 100644 --- a/src/Umbraco.Core/Services/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/EntityXmlSerializer.cs @@ -196,14 +196,11 @@ namespace Umbraco.Cms.Core.Services if (dataType.Level != 1) { //get URL encoded folder names - var folders = _dataTypeService.GetContainers(dataType)? + IOrderedEnumerable folders = _dataTypeService.GetContainers(dataType) .OrderBy(x => x.Level); - if (folders is not null) - { - folderNames = string.Join("/", folders.Select(x => WebUtility.UrlEncode(x.Name)).ToArray()); - folderKeys = string.Join("/", folders.Select(x => x.Key).ToArray()); - } + folderNames = string.Join("/", folders.Select(x => WebUtility.UrlEncode(x.Name)).ToArray()); + folderKeys = string.Join("/", folders.Select(x => x.Key).ToArray()); } if (string.IsNullOrWhiteSpace(folderNames) == false) diff --git a/src/Umbraco.Core/Services/ExternalLoginService.cs b/src/Umbraco.Core/Services/ExternalLoginService.cs index 4fde36ad37..d934e89528 100644 --- a/src/Umbraco.Core/Services/ExternalLoginService.cs +++ b/src/Umbraco.Core/Services/ExternalLoginService.cs @@ -33,12 +33,12 @@ namespace Umbraco.Cms.Core.Services /// [Obsolete("Use overload that takes a user/member key (Guid).")] - public IEnumerable? GetExternalLogins(int userId) + public IEnumerable GetExternalLogins(int userId) => GetExternalLogins(userId.ToGuid()); /// [Obsolete("Use overload that takes a user/member key (Guid).")] - public IEnumerable? GetExternalLoginTokens(int userId) => + public IEnumerable GetExternalLoginTokens(int userId) => GetExternalLoginTokens(userId.ToGuid()); /// @@ -57,32 +57,32 @@ namespace Umbraco.Cms.Core.Services => DeleteUserLogins(userId.ToGuid()); /// - public IEnumerable? GetExternalLogins(Guid userOrMemberKey) + public IEnumerable GetExternalLogins(Guid userOrMemberKey) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { - return _externalLoginRepository.Get(Query().Where(x => x.Key == userOrMemberKey))? + return _externalLoginRepository.Get(Query().Where(x => x.Key == userOrMemberKey)) .ToList(); } } /// - public IEnumerable? GetExternalLoginTokens(Guid userOrMemberKey) + public IEnumerable GetExternalLoginTokens(Guid userOrMemberKey) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { - return _externalLoginRepository.Get(Query().Where(x => x.Key == userOrMemberKey))? + return _externalLoginRepository.Get(Query().Where(x => x.Key == userOrMemberKey)) .ToList(); } } /// - public IEnumerable? Find(string loginProvider, string providerKey) + public IEnumerable Find(string loginProvider, string providerKey) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { return _externalLoginRepository.Get(Query() - .Where(x => x.ProviderKey == providerKey && x.LoginProvider == loginProvider))? + .Where(x => x.ProviderKey == providerKey && x.LoginProvider == loginProvider)) .ToList(); } } diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index 27ec6660e5..2d901ffacd 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -153,7 +153,7 @@ namespace Umbraco.Cms.Core.Services } /// - public Stream? GetStylesheetFileContentStream(string filepath) + public Stream GetStylesheetFileContentStream(string filepath) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -283,7 +283,7 @@ namespace Umbraco.Cms.Core.Services } /// - public Stream? GetScriptFileContentStream(string filepath) + public Stream GetScriptFileContentStream(string filepath) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -597,11 +597,7 @@ namespace Umbraco.Cms.Core.Services fileName = $"{fileName}.cshtml"; } - Stream? fs = _templateRepository.GetFileContentStream(fileName); - if (fs == null) - { - return null; - } + Stream fs = _templateRepository.GetFileContentStream(fileName); using (var view = new StreamReader(fs)) { @@ -610,7 +606,7 @@ namespace Umbraco.Cms.Core.Services } /// - public Stream? GetTemplateFileContentStream(string filepath) + public Stream GetTemplateFileContentStream(string filepath) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -898,7 +894,7 @@ namespace Umbraco.Cms.Core.Services } /// - public Stream? GetPartialViewFileContentStream(string filepath) + public Stream GetPartialViewFileContentStream(string filepath) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -926,7 +922,7 @@ namespace Umbraco.Cms.Core.Services } /// - public Stream? GetPartialViewMacroFileContentStream(string filepath) + public Stream GetPartialViewMacroFileContentStream(string filepath) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { diff --git a/src/Umbraco.Core/Services/IAuditService.cs b/src/Umbraco.Core/Services/IAuditService.cs index cbc3db8239..df816960a3 100644 --- a/src/Umbraco.Core/Services/IAuditService.cs +++ b/src/Umbraco.Core/Services/IAuditService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Querying; @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.Services { void Add(AuditType type, int userId, int objectId, string? entityType, string comment, string? parameters = null); - IEnumerable? GetLogs(int objectId); + IEnumerable GetLogs(int objectId); IEnumerable GetUserLogs(int userId, AuditType type, DateTime? sinceDate = null); IEnumerable GetLogs(AuditType type, DateTime? sinceDate = null); void CleanLogs(int maximumAgeOfLogsInMinutes); diff --git a/src/Umbraco.Core/Services/IConsentService.cs b/src/Umbraco.Core/Services/IConsentService.cs index 50222a7f28..d191caebe2 100644 --- a/src/Umbraco.Core/Services/IConsentService.cs +++ b/src/Umbraco.Core/Services/IConsentService.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Services @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Services /// Determines whether is a start pattern. /// Determines whether to include the history of consents. /// Consents matching the parameters. - IEnumerable? LookupConsent(string? source = null, string? context = null, string? action = null, + IEnumerable LookupConsent(string? source = null, string? context = null, string? action = null, bool sourceStartsWith = false, bool contextStartsWith = false, bool actionStartsWith = false, bool includeHistory = false); } diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index cfc582a5b2..93d51da757 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -26,7 +26,7 @@ namespace Umbraco.Cms.Core.Services /// /// Gets blueprints for a content type. /// - IEnumerable? GetBlueprintsForContentTypes(params int[] documentTypeId); + IEnumerable GetBlueprintsForContentTypes(params int[] documentTypeId); /// /// Saves a blueprint. @@ -89,12 +89,12 @@ namespace Umbraco.Cms.Core.Services /// /// Gets documents. /// - IEnumerable? GetByIds(IEnumerable ids); + IEnumerable GetByIds(IEnumerable ids); /// /// Gets documents at a given level. /// - IEnumerable? GetByLevel(int level); + IEnumerable GetByLevel(int level); /// /// Gets the parent of a document. @@ -109,12 +109,12 @@ namespace Umbraco.Cms.Core.Services /// /// Gets ancestor documents of a document. /// - IEnumerable? GetAncestors(int id); + IEnumerable GetAncestors(int id); /// /// Gets ancestor documents of a document. /// - IEnumerable? GetAncestors(IContent content); + IEnumerable GetAncestors(IContent content); /// /// Gets all versions of a document. diff --git a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs index 17923c61da..c0d5bb96a0 100644 --- a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs +++ b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Umbraco.Cms.Core.Models; @@ -50,8 +50,8 @@ namespace Umbraco.Cms.Core.Services IEnumerable GetDescendants(int id, bool andSelf); // parent-child axis IEnumerable GetComposedOf(int id); // composition axis - IEnumerable? GetChildren(int id); - IEnumerable? GetChildren(Guid id); + IEnumerable GetChildren(int id); + IEnumerable GetChildren(Guid id); bool HasChildren(int id); bool HasChildren(Guid id); diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 4a765ce384..898b24355e 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -22,8 +22,8 @@ namespace Umbraco.Cms.Core.Services EntityContainer? GetContainer(int containerId); EntityContainer? GetContainer(Guid containerId); IEnumerable GetContainers(string folderName, int level); - IEnumerable? GetContainers(IDataType dataType); - IEnumerable? GetContainers(int[] containerIds); + IEnumerable GetContainers(IDataType dataType); + IEnumerable GetContainers(int[] containerIds); Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId); Attempt?> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId); @@ -85,7 +85,7 @@ namespace Umbraco.Cms.Core.Services /// /// Alias of the property editor /// Collection of objects with a matching control id - IEnumerable? GetByEditorAlias(string propertyEditorAlias); + IEnumerable GetByEditorAlias(string propertyEditorAlias); Attempt?> Move(IDataType toMove, int parentId); } diff --git a/src/Umbraco.Core/Services/IExternalLoginService.cs b/src/Umbraco.Core/Services/IExternalLoginService.cs index 05f131919e..75f8069f0c 100644 --- a/src/Umbraco.Core/Services/IExternalLoginService.cs +++ b/src/Umbraco.Core/Services/IExternalLoginService.cs @@ -15,14 +15,14 @@ namespace Umbraco.Cms.Core.Services /// /// /// - IEnumerable? GetExternalLogins(int userId); + IEnumerable GetExternalLogins(int userId); /// /// Returns all user login tokens assigned /// /// /// - IEnumerable? GetExternalLoginTokens(int userId); + IEnumerable GetExternalLoginTokens(int userId); /// /// Returns all logins matching the login info - generally there should only be one but in some cases @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.Services /// /// /// - IEnumerable? Find(string loginProvider, string providerKey); + IEnumerable Find(string loginProvider, string providerKey); /// /// Saves the external logins associated with the user diff --git a/src/Umbraco.Core/Services/IExternalLoginWithKeyService.cs b/src/Umbraco.Core/Services/IExternalLoginWithKeyService.cs index 1b378491c0..bc31f54f8b 100644 --- a/src/Umbraco.Core/Services/IExternalLoginWithKeyService.cs +++ b/src/Umbraco.Core/Services/IExternalLoginWithKeyService.cs @@ -9,18 +9,18 @@ namespace Umbraco.Cms.Core.Services /// /// Returns all user logins assigned /// - IEnumerable? GetExternalLogins(Guid userOrMemberKey); + IEnumerable GetExternalLogins(Guid userOrMemberKey); /// /// Returns all user login tokens assigned /// - IEnumerable? GetExternalLoginTokens(Guid userOrMemberKey); + IEnumerable GetExternalLoginTokens(Guid userOrMemberKey); /// /// Returns all logins matching the login info - generally there should only be one but in some cases /// there might be more than one depending on if an administrator has been editing/removing members /// - IEnumerable? Find(string loginProvider, string providerKey); + IEnumerable Find(string loginProvider, string providerKey); /// /// Saves the external logins associated with the user diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 03798c8597..8d68c20c81 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -36,7 +36,7 @@ namespace Umbraco.Cms.Core.Services /// /// The filesystem path to the partial view. /// The content of the partial view. - Stream? GetPartialViewFileContentStream(string filepath); + Stream GetPartialViewFileContentStream(string filepath); /// /// Sets the content of a partial view. @@ -57,7 +57,7 @@ namespace Umbraco.Cms.Core.Services /// /// The filesystem path to the macro partial view. /// The content of the macro partial view. - Stream? GetPartialViewMacroFileContentStream(string filepath); + Stream GetPartialViewMacroFileContentStream(string filepath); /// /// Sets the content of a macro partial view. @@ -118,7 +118,7 @@ namespace Umbraco.Cms.Core.Services /// /// The filesystem path to the stylesheet. /// The content of the stylesheet. - Stream? GetStylesheetFileContentStream(string filepath); + Stream GetStylesheetFileContentStream(string filepath); /// /// Sets the content of a stylesheet. @@ -179,7 +179,7 @@ namespace Umbraco.Cms.Core.Services /// /// The filesystem path to the script. /// The content of the script file. - Stream? GetScriptFileContentStream(string filepath); + Stream GetScriptFileContentStream(string filepath); /// /// Sets the content of a script file. @@ -274,7 +274,7 @@ namespace Umbraco.Cms.Core.Services /// /// The filesystem path to the template. /// The content of the template. - Stream? GetTemplateFileContentStream(string filepath); + Stream GetTemplateFileContentStream(string filepath); /// /// Sets the content of a template. diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 1ec534029b..ee6ba02b66 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -338,7 +338,7 @@ namespace Umbraco.Cms.Core.Services /// /// The filesystem path to the media. /// The content of the media. - Stream? GetMediaFileContentStream(string filepath); + Stream GetMediaFileContentStream(string filepath); /// /// Sets the content of a media. diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs b/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs index c32362d56c..c91dda8890 100644 --- a/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs +++ b/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs @@ -413,8 +413,8 @@ namespace Umbraco.Cms.Core.Security cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); - var logins = _externalLoginService.Find(loginProvider, providerKey)?.ToList(); - if (logins is null || logins.Count == 0) + var logins = _externalLoginService.Find(loginProvider, providerKey).ToList(); + if (logins.Count == 0) { return Task.FromResult((IdentityUserLogin)null!); } diff --git a/src/Umbraco.Infrastructure/Security/MemberUserStore.cs b/src/Umbraco.Infrastructure/Security/MemberUserStore.cs index 3d8f3447d5..87eb5f363e 100644 --- a/src/Umbraco.Infrastructure/Security/MemberUserStore.cs +++ b/src/Umbraco.Infrastructure/Security/MemberUserStore.cs @@ -440,8 +440,8 @@ namespace Umbraco.Cms.Core.Security throw new ArgumentNullException(nameof(providerKey)); } - var logins = _externalLoginService.Find(loginProvider, providerKey)?.ToList(); - if (logins is null || logins.Count == 0) + var logins = _externalLoginService.Find(loginProvider, providerKey).ToList(); + if (logins.Count == 0) { return Task.FromResult((IdentityUserLogin)null!); } From ea77c9a4fc560e0e64e2f22edeb6085e69c94741 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Fri, 6 May 2022 10:13:58 +0200 Subject: [PATCH 3/5] Further NRT amends (#12363) * Amended nullability of base Deploy classes. * Ensured ContentItemDisplay.Variants is non-nullable. * Set IArtifactSignature.Dependencies to be non-nullable. * Update template collection retrieval to be non-nullable. * IMediaService.GetRootMedia to be non-nullable. * Non-nullable collection for IMemberService.GetMembersByMemberType. * Non-nullable collection for member role retrieval. * Non-nullable collection for root dictionary items. * Non-nullable collection for child dictionary items. * Applied suggestions from code review Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * Remove extra dot Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Co-authored-by: Nikolaj Geisle (cherry picked from commit 63b77b77436aff518685a520841422309d781810) --- src/Umbraco.Core/Deploy/ArtifactBase.cs | 14 ++++------ .../Deploy/ArtifactDeployState.cs | 2 +- .../ArtifactDeployStateOfTArtifactTEntity.cs | 2 +- src/Umbraco.Core/Deploy/IArtifactSignature.cs | 4 +-- .../ContentEditing/ContentItemDisplay.cs | 2 +- .../Models/Mapping/ContentVariantMapper.cs | 16 +++++------- .../Mapping/MemberTabsAndPropertiesMapper.cs | 4 +-- .../Models/Membership/MemberExportModel.cs | 7 ++--- .../Repositories/ITemplateRepository.cs | 4 +-- src/Umbraco.Core/Services/FileService.cs | 8 +++--- src/Umbraco.Core/Services/IFileService.cs | 4 +-- .../Services/ILocalizationService.cs | 6 ++--- src/Umbraco.Core/Services/IMediaService.cs | 2 +- src/Umbraco.Core/Services/IMemberService.cs | 6 ++--- .../Services/IMembershipRoleService.cs | 4 +-- .../Services/LocalizationService.cs | 26 +++++++------------ src/Umbraco.Core/Services/MediaService.cs | 2 +- src/Umbraco.Core/Services/MemberService.cs | 12 ++++----- .../Implement/TemplateRepository.cs | 14 +++++----- .../Mapping/ContentMapDefinition.cs | 6 +++-- 20 files changed, 66 insertions(+), 79 deletions(-) diff --git a/src/Umbraco.Core/Deploy/ArtifactBase.cs b/src/Umbraco.Core/Deploy/ArtifactBase.cs index ff5287d0b8..200b47096d 100644 --- a/src/Umbraco.Core/Deploy/ArtifactBase.cs +++ b/src/Umbraco.Core/Deploy/ArtifactBase.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; - namespace Umbraco.Cms.Core.Deploy { /// @@ -15,13 +11,13 @@ namespace Umbraco.Cms.Core.Deploy Udi = udi ?? throw new ArgumentNullException("udi"); Name = Udi.ToString(); - Dependencies = dependencies ?? Enumerable.Empty(); + _dependencies = dependencies ?? Enumerable.Empty(); _checksum = new Lazy(GetChecksum); } private readonly Lazy _checksum; - private IEnumerable? _dependencies; + private IEnumerable _dependencies; protected abstract string GetChecksum(); @@ -43,16 +39,16 @@ namespace Umbraco.Cms.Core.Deploy /// public bool ShouldSerializeChecksum() => false; - public IEnumerable? Dependencies + public IEnumerable Dependencies { get => _dependencies; - set => _dependencies = value?.OrderBy(x => x.Udi); + set => _dependencies = value.OrderBy(x => x.Udi); } #endregion public string Name { get; set; } - public string? Alias { get; set; } + public string Alias { get; set; } = string.Empty; } } diff --git a/src/Umbraco.Core/Deploy/ArtifactDeployState.cs b/src/Umbraco.Core/Deploy/ArtifactDeployState.cs index 0da78292f2..80a874836f 100644 --- a/src/Umbraco.Core/Deploy/ArtifactDeployState.cs +++ b/src/Umbraco.Core/Deploy/ArtifactDeployState.cs @@ -15,7 +15,7 @@ /// The service connector deploying the artifact. /// The next pass number. /// A deploying artifact. - public static ArtifactDeployState Create(TArtifact art, TEntity entity, IServiceConnector connector, int nextPass) + public static ArtifactDeployState Create(TArtifact art, TEntity? entity, IServiceConnector connector, int nextPass) where TArtifact : IArtifact { return new ArtifactDeployState(art, entity, connector, nextPass); diff --git a/src/Umbraco.Core/Deploy/ArtifactDeployStateOfTArtifactTEntity.cs b/src/Umbraco.Core/Deploy/ArtifactDeployStateOfTArtifactTEntity.cs index bb9a06274e..4150580262 100644 --- a/src/Umbraco.Core/Deploy/ArtifactDeployStateOfTArtifactTEntity.cs +++ b/src/Umbraco.Core/Deploy/ArtifactDeployStateOfTArtifactTEntity.cs @@ -21,7 +21,7 @@ /// The entity. /// The service connector deploying the artifact. /// The next pass number. - public ArtifactDeployState(TArtifact art, TEntity entity, IServiceConnector connector, int nextPass) + public ArtifactDeployState(TArtifact art, TEntity? entity, IServiceConnector connector, int nextPass) { Artifact = art; Entity = entity; diff --git a/src/Umbraco.Core/Deploy/IArtifactSignature.cs b/src/Umbraco.Core/Deploy/IArtifactSignature.cs index edd4d1ad42..695624cd86 100644 --- a/src/Umbraco.Core/Deploy/IArtifactSignature.cs +++ b/src/Umbraco.Core/Deploy/IArtifactSignature.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Umbraco.Cms.Core.Deploy { @@ -36,6 +36,6 @@ namespace Umbraco.Cms.Core.Deploy /// /// Gets the dependencies of this artifact. /// - IEnumerable? Dependencies { get; } + IEnumerable Dependencies { get; } } } diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentItemDisplay.cs b/src/Umbraco.Core/Models/ContentEditing/ContentItemDisplay.cs index 85968222e7..874f2f085a 100644 --- a/src/Umbraco.Core/Models/ContentEditing/ContentItemDisplay.cs +++ b/src/Umbraco.Core/Models/ContentEditing/ContentItemDisplay.cs @@ -65,7 +65,7 @@ namespace Umbraco.Cms.Core.Models.ContentEditing /// If a content item is invariant, this collection will only contain one item, else it will contain all culture variants /// [DataMember(Name = "variants")] - public IEnumerable? Variants { get; set; } + public IEnumerable Variants { get; set; } [DataMember(Name = "owner")] public UserProfile? Owner { get; set; } diff --git a/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs b/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs index 4685fb9cc4..2f330b581f 100644 --- a/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs @@ -19,12 +19,12 @@ namespace Umbraco.Cms.Core.Models.Mapping _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); } - public IEnumerable? Map(IContent source, MapperContext context) where TVariant : ContentVariantDisplay + public IEnumerable Map(IContent source, MapperContext context) where TVariant : ContentVariantDisplay { var variesByCulture = source.ContentType.VariesByCulture(); var variesBySegment = source.ContentType.VariesBySegment(); - IList? variants = new List(); + List variants = new (); if (!variesByCulture && !variesBySegment) { @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Models.Mapping else if (variesByCulture && !variesBySegment) { var languages = GetLanguages(context); - variants = languages? + variants = languages .Select(language => CreateVariantDisplay(context, source, language, null)) .WhereNotNull() .ToList(); @@ -47,7 +47,7 @@ namespace Umbraco.Cms.Core.Models.Mapping { // Segment only var segments = GetSegments(source); - variants = segments? + variants = segments .Select(segment => CreateVariantDisplay(context, source, null, segment)) .WhereNotNull() .ToList(); @@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.Models.Mapping throw new InvalidOperationException("No languages or segments available"); } - variants = languages? + variants = languages .SelectMany(language => segments .Select(segment => CreateVariantDisplay(context, source, language, segment))) .WhereNotNull() @@ -74,11 +74,9 @@ namespace Umbraco.Cms.Core.Models.Mapping return SortVariants(variants); } - - - private IList? SortVariants(IList? variants) where TVariant : ContentVariantDisplay + private IList SortVariants(IList variants) where TVariant : ContentVariantDisplay { - if (variants == null || variants.Count <= 1) + if (variants.Count <= 1) { return variants; } diff --git a/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs index d6d3453a26..9a39051590 100644 --- a/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs @@ -155,9 +155,9 @@ namespace Umbraco.Cms.Core.Models.Mapping return prop; } - internal IDictionary GetMemberGroupValue(string? username) + internal IDictionary GetMemberGroupValue(string username) { - IEnumerable? userRoles = username.IsNullOrWhiteSpace() ? null : _memberService.GetAllRoles(username); + IEnumerable userRoles = _memberService.GetAllRoles(username); // create a dictionary of all roles (except internal roles) + "false" var result = _memberGroupService.GetAll() diff --git a/src/Umbraco.Core/Models/Membership/MemberExportModel.cs b/src/Umbraco.Core/Models/Membership/MemberExportModel.cs index e577c86e70..25ec9730d2 100644 --- a/src/Umbraco.Core/Models/Membership/MemberExportModel.cs +++ b/src/Umbraco.Core/Models/Membership/MemberExportModel.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; - namespace Umbraco.Cms.Core.Models.Membership { public class MemberExportModel @@ -10,10 +7,10 @@ namespace Umbraco.Cms.Core.Models.Membership public string? Name { get; set; } public string? Username { get; set; } public string? Email { get; set; } - public List? Groups { get; set; } + public List Groups { get; set; } = new (); public string? ContentTypeAlias { get; set; } public DateTime CreateDate { get; set; } public DateTime UpdateDate { get; set; } - public List? Properties { get; set; } + public List Properties { get; set; } = new (); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs index fd206d5aff..185973623c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs @@ -7,9 +7,9 @@ namespace Umbraco.Cms.Core.Persistence.Repositories { ITemplate? Get(string? alias); - IEnumerable? GetAll(params string[] aliases); + IEnumerable GetAll(params string[] aliases); - IEnumerable? GetChildren(int masterTemplateId); + IEnumerable GetChildren(int masterTemplateId); IEnumerable GetDescendants(int masterTemplateId); } diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index 2d901ffacd..d692765620 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -412,11 +412,11 @@ namespace Umbraco.Cms.Core.Services /// Gets a list of all objects /// /// An enumerable list of objects - public IEnumerable? GetTemplates(params string[] aliases) + public IEnumerable GetTemplates(params string[] aliases) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { - return _templateRepository.GetAll(aliases)?.OrderBy(x => x.Name); + return _templateRepository.GetAll(aliases).OrderBy(x => x.Name); } } @@ -424,11 +424,11 @@ namespace Umbraco.Cms.Core.Services /// Gets a list of all objects /// /// An enumerable list of objects - public IEnumerable? GetTemplates(int masterTemplateId) + public IEnumerable GetTemplates(int masterTemplateId) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { - return _templateRepository.GetChildren(masterTemplateId)?.OrderBy(x => x.Name); + return _templateRepository.GetChildren(masterTemplateId).OrderBy(x => x.Name); } } diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 8d68c20c81..6cbc06208c 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -199,13 +199,13 @@ namespace Umbraco.Cms.Core.Services /// Gets a list of all objects /// /// An enumerable list of objects - IEnumerable? GetTemplates(params string[] aliases); + IEnumerable GetTemplates(params string[] aliases); /// /// Gets a list of all objects /// /// An enumerable list of objects - IEnumerable? GetTemplates(int masterTemplateId); + IEnumerable GetTemplates(int masterTemplateId); /// /// Gets a object by its alias. diff --git a/src/Umbraco.Core/Services/ILocalizationService.cs b/src/Umbraco.Core/Services/ILocalizationService.cs index f68214cfc3..eca2a8e070 100644 --- a/src/Umbraco.Core/Services/ILocalizationService.cs +++ b/src/Umbraco.Core/Services/ILocalizationService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Umbraco.Cms.Core.Models; @@ -59,7 +59,7 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the parent /// An enumerable list of objects - IEnumerable? GetDictionaryItemChildren(Guid parentId); + IEnumerable GetDictionaryItemChildren(Guid parentId); /// /// Gets a list of descendants for a @@ -72,7 +72,7 @@ namespace Umbraco.Cms.Core.Services /// Gets the root/top objects /// /// An enumerable list of objects - IEnumerable? GetRootDictionaryItems(); + IEnumerable GetRootDictionaryItems(); /// /// Checks if a with given key exists diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index ee6ba02b66..fe14bdda0f 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -130,7 +130,7 @@ namespace Umbraco.Cms.Core.Services /// Gets a collection of objects, which reside at the first level / root /// /// An Enumerable list of objects - IEnumerable? GetRootMedia(); + IEnumerable GetRootMedia(); /// /// Gets a collection of an objects, which resides in the Recycle Bin diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index 6701090915..d6e0480091 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Querying; @@ -127,14 +127,14 @@ namespace Umbraco.Cms.Core.Services /// /// Alias of the MemberType /// - IEnumerable? GetMembersByMemberType(string memberTypeAlias); + IEnumerable GetMembersByMemberType(string memberTypeAlias); /// /// Gets all Members for the MemberType id /// /// Id of the MemberType /// - IEnumerable? GetMembersByMemberType(int memberTypeId); + IEnumerable GetMembersByMemberType(int memberTypeId); /// /// Gets all Members within the specified MemberGroup name diff --git a/src/Umbraco.Core/Services/IMembershipRoleService.cs b/src/Umbraco.Core/Services/IMembershipRoleService.cs index 70e1d53491..5c62a84973 100644 --- a/src/Umbraco.Core/Services/IMembershipRoleService.cs +++ b/src/Umbraco.Core/Services/IMembershipRoleService.cs @@ -12,9 +12,9 @@ namespace Umbraco.Cms.Core.Services IEnumerable GetAllRoles(); - IEnumerable? GetAllRoles(int memberId); + IEnumerable GetAllRoles(int memberId); - IEnumerable GetAllRoles(string? username); + IEnumerable GetAllRoles(string username); IEnumerable GetAllRolesIds(); diff --git a/src/Umbraco.Core/Services/LocalizationService.cs b/src/Umbraco.Core/Services/LocalizationService.cs index ac9d800cb1..262697c935 100644 --- a/src/Umbraco.Core/Services/LocalizationService.cs +++ b/src/Umbraco.Core/Services/LocalizationService.cs @@ -179,18 +179,15 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the parent /// An enumerable list of objects - public IEnumerable? GetDictionaryItemChildren(Guid parentId) + public IEnumerable GetDictionaryItemChildren(Guid parentId) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { var query = Query().Where(x => x.ParentId == parentId); - var items = _dictionaryRepository.Get(query)?.ToArray(); - if (items is not null) - { - //ensure the lazy Language callback is assigned - foreach (var item in items) - EnsureDictionaryItemLanguageCallback(item); - } + var items = _dictionaryRepository.Get(query).ToArray(); + //ensure the lazy Language callback is assigned + foreach (var item in items) + EnsureDictionaryItemLanguageCallback(item); return items; } @@ -217,18 +214,15 @@ namespace Umbraco.Cms.Core.Services /// Gets the root/top objects /// /// An enumerable list of objects - public IEnumerable? GetRootDictionaryItems() + public IEnumerable GetRootDictionaryItems() { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { var query = Query().Where(x => x.ParentId == null); - var items = _dictionaryRepository.Get(query)?.ToArray(); - if (items is not null) - { - //ensure the lazy Language callback is assigned - foreach (var item in items) - EnsureDictionaryItemLanguageCallback(item); - } + var items = _dictionaryRepository.Get(query).ToArray(); + //ensure the lazy Language callback is assigned + foreach (var item in items) + EnsureDictionaryItemLanguageCallback(item); return items; } } diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 446dae4f39..13ba415fee 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -590,7 +590,7 @@ namespace Umbraco.Cms.Core.Services /// Gets a collection of objects, which reside at the first level / root /// /// An Enumerable list of objects - public IEnumerable? GetRootMedia() + public IEnumerable GetRootMedia() { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs index 9d1b9edf9d..2a4498f7e4 100644 --- a/src/Umbraco.Core/Services/MemberService.cs +++ b/src/Umbraco.Core/Services/MemberService.cs @@ -406,7 +406,7 @@ namespace Umbraco.Cms.Core.Services /// /// Alias of the MemberType /// - public IEnumerable? GetMembersByMemberType(string memberTypeAlias) + public IEnumerable GetMembersByMemberType(string memberTypeAlias) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -421,7 +421,7 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the MemberType /// - public IEnumerable? GetMembersByMemberType(int memberTypeId) + public IEnumerable GetMembersByMemberType(int memberTypeId) { using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -894,17 +894,17 @@ namespace Umbraco.Cms.Core.Services /// /// /// A list of member roles - public IEnumerable? GetAllRoles(int memberId) + public IEnumerable GetAllRoles(int memberId) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { scope.ReadLock(Constants.Locks.MemberTree); var result = _memberGroupRepository.GetMemberGroupsForMember(memberId); - return result.Select(x => x.Name).Distinct(); + return result.Select(x => x.Name).WhereNotNull().Distinct(); } } - public IEnumerable GetAllRoles(string? username) + public IEnumerable GetAllRoles(string username) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { @@ -1107,7 +1107,7 @@ namespace Umbraco.Cms.Core.Services Name = member.Name, Username = member.Username, Email = member.Email, - Groups = GetAllRoles(member.Id)?.ToList(), + Groups = GetAllRoles(member.Id).ToList(), ContentTypeAlias = member.ContentTypeAlias, CreateDate = member.CreateDate, UpdateDate = member.UpdateDate, diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs index e214e2ef20..4dc3bb71f2 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs @@ -504,7 +504,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement public ITemplate? Get(string? alias) => GetAll(alias)?.FirstOrDefault(); - public IEnumerable? GetAll(params string?[] aliases) + public IEnumerable GetAll(params string?[] aliases) { //We must call the base (normal) GetAll method // which is cached. This is a specialized method and unfortunately with the params[] it @@ -515,26 +515,26 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement } //return from base.GetAll, this is all cached - return base.GetMany()?.Where(x => aliases.WhereNotNull().InvariantContains(x.Alias)); + return base.GetMany().Where(x => aliases.WhereNotNull().InvariantContains(x.Alias)); } - public IEnumerable? GetChildren(int masterTemplateId) + public IEnumerable GetChildren(int masterTemplateId) { //return from base.GetAll, this is all cached - ITemplate[]? all = base.GetMany()?.ToArray(); + ITemplate[] all = base.GetMany().ToArray(); if (masterTemplateId <= 0) { - return all?.Where(x => x.MasterTemplateAlias.IsNullOrWhiteSpace()); + return all.Where(x => x.MasterTemplateAlias.IsNullOrWhiteSpace()); } - ITemplate? parent = all?.FirstOrDefault(x => x.Id == masterTemplateId); + ITemplate? parent = all.FirstOrDefault(x => x.Id == masterTemplateId); if (parent == null) { return Enumerable.Empty(); } - IEnumerable? children = all?.Where(x => x.MasterTemplateAlias.InvariantEquals(parent.Alias)); + IEnumerable children = all.Where(x => x.MasterTemplateAlias.InvariantEquals(parent.Alias)); return children; } diff --git a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs index 91fda179e2..24cd1c5cbe 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs @@ -160,8 +160,10 @@ namespace Umbraco.Cms.Web.BackOffice.Mapping target.Urls = GetUrls(source); target.Variants = _contentVariantMapper.Map(source, context); - target.ContentDto = new ContentPropertyCollectionDto(); - target.ContentDto.Properties = context.MapEnumerable(source.Properties).WhereNotNull(); + target.ContentDto = new ContentPropertyCollectionDto + { + Properties = context.MapEnumerable(source.Properties).WhereNotNull() + }; } // Umbraco.Code.MapAll -Segment -Language -DisplayName From 5810c2d35b4b8d94b28a99d3be0c537657a61aa0 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Fri, 6 May 2022 18:04:26 +0200 Subject: [PATCH 4/5] Further NRT updates for Deploy (#12375) * Nullability modifications to grid cell values and connector. * Nullable updates to IDataTypeConfigurationConnector. * Apply suggestions from code review Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> (cherry picked from commit 109d2f191eeb9e0943402db7da71635007a98ccc) --- src/Umbraco.Core/Deploy/IDataTypeConfigurationConnector.cs | 4 ++-- src/Umbraco.Infrastructure/Deploy/IGridCellValueConnector.cs | 4 ++-- src/Umbraco.Infrastructure/Models/GridValue.cs | 4 ++-- .../PropertyEditors/GridPropertyEditor.cs | 4 ++-- .../Templates/HtmlMacroParameterParser.cs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/Deploy/IDataTypeConfigurationConnector.cs b/src/Umbraco.Core/Deploy/IDataTypeConfigurationConnector.cs index 548a6d80f1..87a00e7969 100644 --- a/src/Umbraco.Core/Deploy/IDataTypeConfigurationConnector.cs +++ b/src/Umbraco.Core/Deploy/IDataTypeConfigurationConnector.cs @@ -22,13 +22,13 @@ namespace Umbraco.Cms.Core.Deploy /// /// The datatype. /// The dependencies. - string ToArtifact(IDataType dataType, ICollection dependencies); + string? ToArtifact(IDataType dataType, ICollection dependencies); /// /// Gets the actual datatype configuration corresponding to the artifact configuration. /// /// The datatype. /// The artifact configuration. - object FromArtifact(IDataType dataType, string configuration); + object? FromArtifact(IDataType dataType, string? configuration); } } diff --git a/src/Umbraco.Infrastructure/Deploy/IGridCellValueConnector.cs b/src/Umbraco.Infrastructure/Deploy/IGridCellValueConnector.cs index 40c0b98474..94dabf7b4f 100644 --- a/src/Umbraco.Infrastructure/Deploy/IGridCellValueConnector.cs +++ b/src/Umbraco.Infrastructure/Deploy/IGridCellValueConnector.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Deploy @@ -25,7 +25,7 @@ namespace Umbraco.Cms.Core.Deploy /// The dependencies of the property. /// The grid cell value to be deployed. /// Note that - string GetValue(GridValue.GridControl gridControl, ICollection dependencies); + string? GetValue(GridValue.GridControl gridControl, ICollection dependencies); /// /// Allows you to modify the value of a control being deployed. diff --git a/src/Umbraco.Infrastructure/Models/GridValue.cs b/src/Umbraco.Infrastructure/Models/GridValue.cs index e873287ffb..a83d235b55 100644 --- a/src/Umbraco.Infrastructure/Models/GridValue.cs +++ b/src/Umbraco.Infrastructure/Models/GridValue.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -63,7 +63,7 @@ namespace Umbraco.Cms.Core.Models public class GridControl { [JsonProperty("value")] - public JToken Value { get; set; } = null!; + public JToken? Value { get; set; } [JsonProperty("editor")] public GridEditor Editor { get; set; } = null!; diff --git a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs index ca2dcefbbf..a0423a41f0 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs @@ -300,8 +300,8 @@ namespace Umbraco.Cms.Core.PropertyEditors if (mediaValues is not null) { - foreach (var umbracoEntityReference in mediaValues.Where(x => x.Value.HasValues) - .SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"]))) + foreach (var umbracoEntityReference in mediaValues.Where(x => x.Value?.HasValues ?? false) + .SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value!["udi"]))) { yield return umbracoEntityReference; } diff --git a/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs b/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs index fc6e08c0cd..7522585f47 100644 --- a/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs +++ b/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs @@ -57,7 +57,7 @@ namespace Umbraco.Cms.Infrastructure.Templates foreach (var macroGridControl in macroGridControls) { // Deserialise JSON of Macro Grid Control to a class - var gridMacro = macroGridControl.Value.ToObject(); + var gridMacro = macroGridControl.Value?.ToObject(); // Collect any macro parameters that contain the media udi format if (gridMacro is not null && gridMacro.MacroParameters is not null && gridMacro.MacroParameters.Any()) { From 62fb7a6f19763c7127fa1a046cc2331df416dcaa Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Sat, 7 May 2022 12:06:33 +0200 Subject: [PATCH 5/5] Fixed issue with null reference when obtaining a lock using a detached scope. (cherry picked from commit 02cd139770c7ad7716c951d8d93c3675164dbd2b) --- .../Scoping/IScopeProvider.cs | 4 +++- src/Umbraco.Infrastructure/Scoping/Scope.cs | 20 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Infrastructure/Scoping/IScopeProvider.cs b/src/Umbraco.Infrastructure/Scoping/IScopeProvider.cs index c29ce56a82..a41c64eb08 100644 --- a/src/Umbraco.Infrastructure/Scoping/IScopeProvider.cs +++ b/src/Umbraco.Infrastructure/Scoping/IScopeProvider.cs @@ -74,7 +74,9 @@ public interface IScopeProvider : ICoreScopeProvider /// A detached scope is not ambient and has no parent. /// It is meant to be attached by . /// - // TODO: This is not actually used apart from unit tests - I'm assuming it's maybe used by Deploy? + /// + /// This is not used by CMS but is used by Umbraco Deploy. + /// IScope CreateDetachedScope( IsolationLevel isolationLevel = IsolationLevel.Unspecified, RepositoryCacheMode repositoryCacheMode = RepositoryCacheMode.Unspecified, diff --git a/src/Umbraco.Infrastructure/Scoping/Scope.cs b/src/Umbraco.Infrastructure/Scoping/Scope.cs index f46ee443f8..190261a808 100644 --- a/src/Umbraco.Infrastructure/Scoping/Scope.cs +++ b/src/Umbraco.Infrastructure/Scoping/Scope.cs @@ -130,6 +130,8 @@ namespace Umbraco.Cms.Infrastructure.Scoping _fscope = fileSystems.Shadow(); } + _acquiredLocks = new Queue(); + return; } @@ -1204,7 +1206,14 @@ namespace Umbraco.Cms.Infrastructure.Scoping /// Lock object identifier to lock. /// TimeSpan specifying the timout period. private void ObtainReadLock(int lockId, TimeSpan? timeout) - => _acquiredLocks!.Enqueue(_scopeProvider.DistributedLockingMechanismFactory.DistributedLockingMechanism.ReadLock(lockId, timeout)); + { + if (_acquiredLocks == null) + { + throw new InvalidOperationException($"Cannot obtain a read lock as the {nameof(_acquiredLocks)} queue is null."); + } + + _acquiredLocks.Enqueue(_scopeProvider.DistributedLockingMechanismFactory.DistributedLockingMechanism.ReadLock(lockId, timeout)); + } /// /// Obtains a write lock with a custom timeout. @@ -1212,6 +1221,13 @@ namespace Umbraco.Cms.Infrastructure.Scoping /// Lock object identifier to lock. /// TimeSpan specifying the timout period. private void ObtainWriteLock(int lockId, TimeSpan? timeout) - => _acquiredLocks!.Enqueue(_scopeProvider.DistributedLockingMechanismFactory.DistributedLockingMechanism.WriteLock(lockId, timeout)); + { + if (_acquiredLocks == null) + { + throw new InvalidOperationException($"Cannot obtain a write lock as the {nameof(_acquiredLocks)} queue is null."); + } + + _acquiredLocks.Enqueue(_scopeProvider.DistributedLockingMechanismFactory.DistributedLockingMechanism.WriteLock(lockId, timeout)); + } } }