diff --git a/src/Umbraco.Core/Cache/AppCacheExtensions.cs b/src/Umbraco.Core/Cache/AppCacheExtensions.cs index d41f1119ed..f5e92cc116 100644 --- a/src/Umbraco.Core/Cache/AppCacheExtensions.cs +++ b/src/Umbraco.Core/Cache/AppCacheExtensions.cs @@ -31,7 +31,7 @@ namespace Umbraco.Extensions provider.Insert(cacheKey, () => getCacheItem(), timeout, isSliding, dependentFiles); } - public static IEnumerable? GetCacheItemsByKeySearch(this IAppCache provider, string keyStartsWith) + public static IEnumerable GetCacheItemsByKeySearch(this IAppCache provider, string keyStartsWith) { var result = provider.SearchByKey(keyStartsWith); return result.Select(x => x.TryConvertTo().Result); diff --git a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs index 92669159f1..a6b705ae5d 100644 --- a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs +++ b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs @@ -44,7 +44,7 @@ namespace Umbraco.Cms.Core.Cache /// /// The json payload. /// The deserialized object payload. - public TJsonPayload[] Deserialize(string json) + public TJsonPayload[]? Deserialize(string json) { return JsonSerializer.Deserialize(json); } diff --git a/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs index 7c912d5c22..e01f7b2458 100644 --- a/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs +++ b/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.Cache public static NoCacheRepositoryCachePolicy Instance { get; } = new NoCacheRepositoryCachePolicy(); - public TEntity Get(TId id, Func performGet, Func> performGetAll) + public TEntity? Get(TId? id, Func performGet, Func?> performGetAll) { return performGet(id); } @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.Cache return null; } - public bool Exists(TId id, Func performExists, Func> performGetAll) + public bool Exists(TId id, Func performExists, Func?> performGetAll) { return performExists(id); } @@ -42,9 +42,9 @@ namespace Umbraco.Cms.Core.Cache persistDeleted(entity); } - public TEntity?[] GetAll(TId[] ids, Func> performGetAll) + public TEntity[]? GetAll(TId[]? ids, Func?> performGetAll) { - return performGetAll(ids).ToArray(); + return performGetAll(ids)?.ToArray(); } public void ClearAll() diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs index 3abc688c01..db5d669ce9 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs @@ -45,7 +45,7 @@ namespace Umbraco.Cms.Core.Configuration.Grid try { - editors.AddRange(_jsonSerializer.Deserialize>(sourceString)); + editors.AddRange(_jsonSerializer.Deserialize>(sourceString)!); } catch (Exception ex) { @@ -62,7 +62,7 @@ namespace Umbraco.Cms.Core.Configuration.Grid { using var reader = new StreamReader(resourceStream, Encoding.UTF8); var sourceString = reader.ReadToEnd(); - editors.AddRange(_jsonSerializer.Deserialize>(sourceString)); + editors.AddRange(_jsonSerializer.Deserialize>(sourceString)!); } } diff --git a/src/Umbraco.Core/Events/UserNotificationsHandler.cs b/src/Umbraco.Core/Events/UserNotificationsHandler.cs index 61ac33a5c0..61bcde6a1b 100644 --- a/src/Umbraco.Core/Events/UserNotificationsHandler.cs +++ b/src/Umbraco.Core/Events/UserNotificationsHandler.cs @@ -217,22 +217,22 @@ namespace Umbraco.Cms.Core.Events public void Handle(AssignedUserGroupPermissionsNotification notification) { - var entities = _contentService.GetByIds(notification.EntityPermissions.Select(e => e.EntityId)).ToArray(); - if (entities.Any() == false) + var entities = _contentService.GetByIds(notification.EntityPermissions.Select(e => e.EntityId))?.ToArray(); + if (entities?.Any() == false) { return; } - _notifier.Notify(_actions.GetAction(), entities); + _notifier.Notify(_actions.GetAction(), entities!); } public void Handle(PublicAccessEntrySavedNotification notification) { - var entities = _contentService.GetByIds(notification.SavedEntities.Select(e => e.ProtectedNodeId)).ToArray(); - if (entities.Any() == false) + var entities = _contentService.GetByIds(notification.SavedEntities.Select(e => e.ProtectedNodeId))?.ToArray(); + if (entities?.Any() == false) { return; } - _notifier.Notify(_actions.GetAction(), entities); + _notifier.Notify(_actions.GetAction(), entities!); } } } diff --git a/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs b/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs index d1d71a9ca1..27331d31a5 100644 --- a/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs +++ b/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs @@ -150,8 +150,8 @@ namespace Umbraco.Extensions /// Allowed apps /// Roles public static void AddRequiredClaims(this ClaimsIdentity identity, string userId, string username, - string? realName, IEnumerable? startContentNodes, IEnumerable? startMediaNodes, string culture, - string securityStamp, IEnumerable allowedApps, IEnumerable roles) + string realName, IEnumerable? startContentNodes, IEnumerable? startMediaNodes, string culture, + string securityStamp, IEnumerable allowedApps, IEnumerable roles) { //This is the id that 'identity' uses to check for the user id if (identity.HasClaim(x => x.Type == ClaimTypes.NameIdentifier) == false) diff --git a/src/Umbraco.Core/IO/IFileSystem.cs b/src/Umbraco.Core/IO/IFileSystem.cs index 853b91f663..232827300c 100644 --- a/src/Umbraco.Core/IO/IFileSystem.cs +++ b/src/Umbraco.Core/IO/IFileSystem.cs @@ -97,7 +97,7 @@ namespace Umbraco.Cms.Core.IO /// /// True if the file exists and the user has permission to view it; otherwise false. /// - bool FileExists(string? path); + bool FileExists(string path); /// /// Returns the application relative path to the file. diff --git a/src/Umbraco.Core/Install/InstallStatusTracker.cs b/src/Umbraco.Core/Install/InstallStatusTracker.cs index 43e2f477a4..1ee7f685d4 100644 --- a/src/Umbraco.Core/Install/InstallStatusTracker.cs +++ b/src/Umbraco.Core/Install/InstallStatusTracker.cs @@ -66,9 +66,12 @@ namespace Umbraco.Cms.Core.Install { var deserialized = _jsonSerializer.Deserialize>( File.ReadAllText(file)); - foreach (var item in deserialized) + if (deserialized is not null) { - _steps.Add(item); + foreach (var item in deserialized) + { + _steps.Add(item); + } } } else @@ -89,9 +92,12 @@ namespace Umbraco.Cms.Core.Install { var deserialized = _jsonSerializer.Deserialize>( File.ReadAllText(file)); - foreach (var item in deserialized) + if (deserialized is not null) { - _steps.Add(item); + foreach (var item in deserialized) + { + _steps.Add(item); + } } } else diff --git a/src/Umbraco.Core/Install/InstallSteps/UpgradeStep.cs b/src/Umbraco.Core/Install/InstallSteps/UpgradeStep.cs index 93290cc249..6530983de2 100644 --- a/src/Umbraco.Core/Install/InstallSteps/UpgradeStep.cs +++ b/src/Umbraco.Core/Install/InstallSteps/UpgradeStep.cs @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.Install.InstallSteps { get { - string FormatGuidState(string value) + string FormatGuidState(string? value) { if (string.IsNullOrWhiteSpace(value)) value = "unknown"; else if (Guid.TryParse(value, out var currentStateGuid)) diff --git a/src/Umbraco.Core/Macros/IMacroRenderer.cs b/src/Umbraco.Core/Macros/IMacroRenderer.cs index 473959f94f..bac3d36268 100644 --- a/src/Umbraco.Core/Macros/IMacroRenderer.cs +++ b/src/Umbraco.Core/Macros/IMacroRenderer.cs @@ -9,6 +9,6 @@ namespace Umbraco.Cms.Core.Macros /// public interface IMacroRenderer { - Task RenderAsync(string macroAlias, IPublishedContent? content, IDictionary macroParams); + Task RenderAsync(string macroAlias, IPublishedContent? content, IDictionary? macroParams); } } diff --git a/src/Umbraco.Core/Manifest/IManifestParser.cs b/src/Umbraco.Core/Manifest/IManifestParser.cs index 14e3d01cca..09d3ccbe1c 100644 --- a/src/Umbraco.Core/Manifest/IManifestParser.cs +++ b/src/Umbraco.Core/Manifest/IManifestParser.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.Manifest /// Gets all manifests, merged into a single manifest object. /// /// - CompositePackageManifest? CombinedManifest { get; } + CompositePackageManifest CombinedManifest { get; } /// /// Parses a manifest. diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Core/Manifest/PackageManifest.cs index 14ff1165cd..a71cf1f6f6 100644 --- a/src/Umbraco.Core/Manifest/PackageManifest.cs +++ b/src/Umbraco.Core/Manifest/PackageManifest.cs @@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.Manifest /// An optional package name. If not specified then the directory name is used. /// [DataMember(Name = "name")] - public string PackageName + public string? PackageName { get { diff --git a/src/Umbraco.Core/Mapping/MapperContext.cs b/src/Umbraco.Core/Mapping/MapperContext.cs index 4bc4455e67..2e128e2475 100644 --- a/src/Umbraco.Core/Mapping/MapperContext.cs +++ b/src/Umbraco.Core/Mapping/MapperContext.cs @@ -37,7 +37,7 @@ namespace Umbraco.Cms.Core.Mapping /// The target type. /// The source object. /// The target object. - public TTarget Map(object source) + public TTarget? Map(object source) => _mapper.Map(source, this); // let's say this is a bad (dangerous) idea, and leave it out for now @@ -63,7 +63,7 @@ namespace Umbraco.Cms.Core.Mapping /// The target type. /// The source object. /// The target object. - public TTarget Map(TSource? source) + public TTarget? Map(TSource? source) => _mapper.Map(source, this); // let's say this is a bad (dangerous) idea, and leave it out for now diff --git a/src/Umbraco.Core/Media/EmbedProviders/OEmbedProviderBase.cs b/src/Umbraco.Core/Media/EmbedProviders/OEmbedProviderBase.cs index 7fafc232df..31ea975164 100644 --- a/src/Umbraco.Core/Media/EmbedProviders/OEmbedProviderBase.cs +++ b/src/Umbraco.Core/Media/EmbedProviders/OEmbedProviderBase.cs @@ -61,7 +61,7 @@ namespace Umbraco.Cms.Core.Media.EmbedProviders } } - public virtual T GetJsonResponse(string url) where T : class + public virtual T? GetJsonResponse(string url) where T : class { var response = DownloadResponse(url); return _jsonSerializer.Deserialize(response); diff --git a/src/Umbraco.Core/Models/DictionaryItem.cs b/src/Umbraco.Core/Models/DictionaryItem.cs index 359d6de01c..14cd3bb2e5 100644 --- a/src/Umbraco.Core/Models/DictionaryItem.cs +++ b/src/Umbraco.Core/Models/DictionaryItem.cs @@ -75,7 +75,7 @@ namespace Umbraco.Cms.Core.Models } } - SetPropertyValueAndDetectChanges(asArray, ref _translations, nameof(Translations), + SetPropertyValueAndDetectChanges(asArray, ref _translations!, nameof(Translations), DictionaryTranslationComparer); } } diff --git a/src/Umbraco.Core/Models/DictionaryTranslation.cs b/src/Umbraco.Core/Models/DictionaryTranslation.cs index 11b1229206..d0d98a64db 100644 --- a/src/Umbraco.Core/Models/DictionaryTranslation.cs +++ b/src/Umbraco.Core/Models/DictionaryTranslation.cs @@ -14,11 +14,11 @@ namespace Umbraco.Cms.Core.Models public Func? GetLanguage { get; set; } private ILanguage? _language; - private string? _value; + private string _value; //note: this will be memberwise cloned private int _languageId; - public DictionaryTranslation(ILanguage language, string? value) + public DictionaryTranslation(ILanguage language, string value) { if (language == null) throw new ArgumentNullException("language"); _language = language; @@ -88,10 +88,10 @@ namespace Umbraco.Cms.Core.Models /// Gets or sets the translated text /// [DataMember] - public string? Value + public string Value { get { return _value; } - set { SetPropertyValueAndDetectChanges(value, ref _value, nameof(Value)); } + set { SetPropertyValueAndDetectChanges(value, ref _value!, nameof(Value)); } } protected override void PerformDeepClone(object clone) diff --git a/src/Umbraco.Core/Models/Email/NotificationEmailModel.cs b/src/Umbraco.Core/Models/Email/NotificationEmailModel.cs index f27b279c80..c71519d83f 100644 --- a/src/Umbraco.Core/Models/Email/NotificationEmailModel.cs +++ b/src/Umbraco.Core/Models/Email/NotificationEmailModel.cs @@ -8,19 +8,19 @@ namespace Umbraco.Cms.Core.Models.Email /// public class NotificationEmailModel { - public NotificationEmailAddress From { get; } + public NotificationEmailAddress? From { get; } - public IEnumerable To { get; } + public IEnumerable? To { get; } - public IEnumerable Cc { get; } + public IEnumerable? Cc { get; } - public IEnumerable Bcc { get; } + public IEnumerable? Bcc { get; } - public IEnumerable ReplyTo { get; } + public IEnumerable? ReplyTo { get; } - public string Subject { get; } + public string? Subject { get; } - public string Body { get; } + public string? Body { get; } public bool IsBodyHtml { get; } diff --git a/src/Umbraco.Core/Models/Entities/ITreeEntity.cs b/src/Umbraco.Core/Models/Entities/ITreeEntity.cs index b970f46726..0024a7cdc4 100644 --- a/src/Umbraco.Core/Models/Entities/ITreeEntity.cs +++ b/src/Umbraco.Core/Models/Entities/ITreeEntity.cs @@ -8,7 +8,7 @@ /// /// Gets or sets the name of the entity. /// - string Name { get; set; } + string? Name { get; set; } /// /// Gets or sets the identifier of the user who created this entity. diff --git a/src/Umbraco.Core/Models/Entities/TreeEntityBase.cs b/src/Umbraco.Core/Models/Entities/TreeEntityBase.cs index 54befb1f1f..de54009ccd 100644 --- a/src/Umbraco.Core/Models/Entities/TreeEntityBase.cs +++ b/src/Umbraco.Core/Models/Entities/TreeEntityBase.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Models.Entities public string? Name { get => _name; - set => SetPropertyValueAndDetectChanges(value, ref _name!, nameof(Name)); + set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name)); } /// diff --git a/src/Umbraco.Core/Models/ILanguage.cs b/src/Umbraco.Core/Models/ILanguage.cs index d392e2bb37..fc20642464 100644 --- a/src/Umbraco.Core/Models/ILanguage.cs +++ b/src/Umbraco.Core/Models/ILanguage.cs @@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.Models /// Gets or sets the culture name of the language. /// [DataMember] - string CultureName { get; set; } + string? CultureName { get; set; } /// /// Gets the object for the language. diff --git a/src/Umbraco.Core/Models/IRedirectUrl.cs b/src/Umbraco.Core/Models/IRedirectUrl.cs index 18498837b4..f2e4e131a7 100644 --- a/src/Umbraco.Core/Models/IRedirectUrl.cs +++ b/src/Umbraco.Core/Models/IRedirectUrl.cs @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Models /// /// Is a proper Umbraco route eg /path/to/foo or 123/path/tofoo. [DataMember] - string Url { get; set; } + string? Url { get; set; } } } diff --git a/src/Umbraco.Core/Models/Macro.cs b/src/Umbraco.Core/Models/Macro.cs index bccb1bbb83..1e395c2158 100644 --- a/src/Umbraco.Core/Models/Macro.cs +++ b/src/Umbraco.Core/Models/Macro.cs @@ -27,6 +27,7 @@ namespace Umbraco.Cms.Core.Models _properties.CollectionChanged += PropertiesChanged; _addedProperties = new List(); _removedProperties = new List(); + _macroSource = string.Empty; } /// @@ -69,7 +70,7 @@ namespace Umbraco.Cms.Core.Models /// /// public Macro(IShortStringHelper shortStringHelper, string @alias, string? name, - string? macroSource, + string macroSource, bool cacheByPage = false, bool cacheByMember = false, bool dontRender = true, @@ -94,7 +95,7 @@ namespace Umbraco.Cms.Core.Models private bool _cacheByPage; private bool _cacheByMember; private bool _dontRender; - private string? _macroSource; + private string _macroSource; private MacroPropertyCollection _properties; private List _addedProperties; private List _removedProperties; @@ -245,10 +246,10 @@ namespace Umbraco.Cms.Core.Models /// Gets or set the path to the Partial View to render /// [DataMember] - public string? MacroSource + public string MacroSource { get => _macroSource; - set => SetPropertyValueAndDetectChanges(value, ref _macroSource, nameof(MacroSource)); + set => SetPropertyValueAndDetectChanges(value, ref _macroSource!, nameof(MacroSource)); } /// diff --git a/src/Umbraco.Core/Models/Membership/User.cs b/src/Umbraco.Core/Models/Membership/User.cs index f5a4a87db7..91ef03bd4a 100644 --- a/src/Umbraco.Core/Models/Membership/User.cs +++ b/src/Umbraco.Core/Models/Membership/User.cs @@ -32,6 +32,7 @@ namespace Umbraco.Cms.Core.Models.Membership _rawPasswordValue = ""; _username = string.Empty; _email = string.Empty; + _name = string.Empty; } /// @@ -72,7 +73,7 @@ namespace Umbraco.Cms.Core.Models.Membership /// /// /// - public User(GlobalSettings globalSettings, int id, string? name, string? email, string? username, + public User(GlobalSettings globalSettings, int id, string? name, string email, string? username, string? rawPasswordValue, string? passwordConfig, IEnumerable userGroups, int[] startContentIds, int[] startMediaIds) : this(globalSettings) @@ -98,7 +99,7 @@ namespace Umbraco.Cms.Core.Models.Membership _startMediaIds = startMediaIds; } - private string? _name; + private string _name; private string? _securityStamp; private string? _avatar; private string? _tourData; @@ -111,7 +112,7 @@ namespace Umbraco.Cms.Core.Models.Membership private DateTime? _emailConfirmedDate; private DateTime? _invitedDate; private string _email; - private string _rawPasswordValue; + private string? _rawPasswordValue; private string? _passwordConfig; private IEnumerable? _allowedSections; private HashSet _userGroups; @@ -158,7 +159,7 @@ namespace Umbraco.Cms.Core.Models.Membership } [IgnoreDataMember] - public string RawPasswordValue + public string? RawPasswordValue { get => _rawPasswordValue; set => SetPropertyValueAndDetectChanges(value, ref _rawPasswordValue, nameof(RawPasswordValue)); @@ -237,10 +238,10 @@ namespace Umbraco.Cms.Core.Models.Membership } [DataMember] - public string? Name + public string Name { get => _name; - set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name)); + set => SetPropertyValueAndDetectChanges(value, ref _name!, nameof(Name)); } public IEnumerable AllowedSections diff --git a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs b/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs index 34f4f83755..4497d6be4d 100644 --- a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs +++ b/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs @@ -10,8 +10,8 @@ namespace Umbraco.Cms.Core.Models.Packaging /// public class CompiledPackage { - public FileInfo PackageFile { get; set; } = null!; - public string Name { get; set; } = string.Empty; + public FileInfo? PackageFile { get; set; } + public string? Name { get; set; } public InstallWarnings Warnings { get; set; } = new InstallWarnings(); public IEnumerable Macros { get; set; } = null!; // TODO: make strongly typed public IEnumerable MacroPartialViews { get; set; } = null!; // TODO: make strongly typed diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index 4dc4bc05a0..9a8daac0c4 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.Serialization; using Umbraco.Extensions; @@ -145,7 +146,7 @@ namespace Umbraco.Cms.Core.Models } } - public bool TryGetValue(string propertyTypeAlias, out IProperty? property) + public bool TryGetValue(string propertyTypeAlias, [MaybeNullWhen(false)] out IProperty property) { property = this.FirstOrDefault(x => x.Alias?.InvariantEquals(propertyTypeAlias) ?? false); return property != null; diff --git a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs index 66716876e9..ebcf073a63 100644 --- a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs @@ -25,7 +25,7 @@ namespace Umbraco.Extensions var tagAttribute = editor?.GetTagAttribute(); if (tagAttribute == null) return null; - var configurationObject = property.PropertyType is null ? null : dataTypeService.GetDataType(property.PropertyType.DataTypeId).Configuration; + var configurationObject = property.PropertyType is null ? null : dataTypeService.GetDataType(property.PropertyType.DataTypeId)?.Configuration; var configuration = ConfigurationEditor.ConfigurationAs(configurationObject); if (configuration?.Delimiter == default && configuration?.Delimiter is not null) @@ -165,7 +165,7 @@ namespace Umbraco.Extensions case TagsStorageType.Json: try { - return serializer.Deserialize(value).Select(x => x.Trim()); + return serializer.Deserialize(value)?.Select(x => x.Trim()) ?? Enumerable.Empty(); } catch (Exception) { diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index d8a71f4cfa..3acbad2720 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -89,6 +89,7 @@ namespace Umbraco.Cms.Core.Models _forceValueStorageType = forceValueStorageType; _alias = propertyTypeAlias == null ? string.Empty : SanitizeAlias(propertyTypeAlias); _variations = ContentVariation.Nothing; + _name = string.Empty; } /// diff --git a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/NoopPublishedModelFactory.cs index d3f97a893d..f53a5236a9 100644 --- a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/NoopPublishedModelFactory.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent public IPublishedElement CreateModel(IPublishedElement element) => element; /// - public IList CreateModelList(string alias) => new List(); + public IList CreateModelList(string? alias) => new List(); /// public Type MapModelType(Type type) => typeof(IPublishedElement); diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs index 31a05123b1..accbbab6e2 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs @@ -78,19 +78,19 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// public PublishedDataType GetDataType(int id) { - Dictionary publishedDataTypes; + Dictionary? publishedDataTypes; lock (_publishedDataTypesLocker) { if (_publishedDataTypes == null) { var dataTypes = _dataTypeService.GetAll(); - _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); + _publishedDataTypes = dataTypes?.ToDictionary(x => x.Id, CreatePublishedDataType); } publishedDataTypes = _publishedDataTypes; } - if (!publishedDataTypes.TryGetValue(id, out var dataType)) + if (publishedDataTypes is null || !publishedDataTypes.TryGetValue(id, out var dataType)) throw new ArgumentException($"Could not find a datatype with identifier {id}.", nameof(id)); return dataType; @@ -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,8 +112,11 @@ namespace Umbraco.Cms.Core.Models.PublishedContent _publishedDataTypes.Remove(id); var dataTypes = _dataTypeService.GetAll(ids); - foreach (var dataType in dataTypes) - _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); + if (dataTypes is not null) + { + foreach (var dataType in dataTypes) + _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); + } } } } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs index 3c8ae6b3d2..2d40874b57 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs @@ -104,13 +104,13 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public IList? CreateModelList(string alias) + public IList? CreateModelList(string? alias) { // fail fast if (_modelInfos == null) return new List(); - if (!_modelInfos.TryGetValue(alias, out var modelInfo) || modelInfo.ModelType is null) + if (alias is null || !_modelInfos.TryGetValue(alias, out var modelInfo) || modelInfo.ModelType is null) return new List(); var ctor = modelInfo.ListCtor; diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs index 002848a758..9420811f24 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs @@ -240,12 +240,12 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public Type? ModelClrType + public Type ModelClrType { get { if (!_initialized) Initialize(); - return _modelClrType; + return _modelClrType!; } } diff --git a/src/Umbraco.Core/Models/Relation.cs b/src/Umbraco.Core/Models/Relation.cs index 7cb447ccc3..54227db910 100644 --- a/src/Umbraco.Core/Models/Relation.cs +++ b/src/Umbraco.Core/Models/Relation.cs @@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.Models //NOTE: The datetime column from umbracoRelation is set on CreateDate on the Entity private int _parentId; private int _childId; - private IRelationType? _relationType; + private IRelationType _relationType; private string? _comment; /// @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Models /// /// /// - public Relation(int parentId, int childId, Guid parentObjectType, Guid childObjectType, IRelationType? relationType) + public Relation(int parentId, int childId, Guid parentObjectType, Guid childObjectType, IRelationType relationType) { _parentId = parentId; _childId = childId; diff --git a/src/Umbraco.Core/Models/Tag.cs b/src/Umbraco.Core/Models/Tag.cs index 428f9583d0..92436d068b 100644 --- a/src/Umbraco.Core/Models/Tag.cs +++ b/src/Umbraco.Core/Models/Tag.cs @@ -11,8 +11,8 @@ namespace Umbraco.Cms.Core.Models [DataContract(IsReference = true)] public class Tag : EntityBase, ITag { - private string? _group; - private string? _text; + private string _group = string.Empty; + private string _text = string.Empty; private int? _languageId; /// @@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.Models /// /// Initializes a new instance of the class. /// - public Tag(int id, string? group, string? text, int? languageId = null) + public Tag(int id, string group, string text, int? languageId = null) { Id = id; Text = text; @@ -33,17 +33,17 @@ namespace Umbraco.Cms.Core.Models } /// - public string? Group + public string Group { get => _group; - set => SetPropertyValueAndDetectChanges(value, ref _group, nameof(Group)); + set => SetPropertyValueAndDetectChanges(value, ref _group!, nameof(Group)); } /// - public string? Text + public string Text { get => _text; - set => SetPropertyValueAndDetectChanges(value, ref _text, nameof(Text)); + set => SetPropertyValueAndDetectChanges(value, ref _text!, nameof(Text)); } /// diff --git a/src/Umbraco.Core/Models/UserExtensions.cs b/src/Umbraco.Core/Models/UserExtensions.cs index ba63780975..4d0fefd16c 100644 --- a/src/Umbraco.Core/Models/UserExtensions.cs +++ b/src/Umbraco.Core/Models/UserExtensions.cs @@ -25,7 +25,7 @@ namespace Umbraco.Cms.Core.Models /// /// A list of 5 different sized avatar URLs /// - public static string[] GetUserAvatarUrls(this IUser user, IAppCache cache, MediaFileManager mediaFileManager, IImageUrlGenerator imageUrlGenerator) + public static string?[] GetUserAvatarUrls(this IUser user, IAppCache cache, MediaFileManager mediaFileManager, IImageUrlGenerator imageUrlGenerator) { // If FIPS is required, never check the Gravatar service as it only supports MD5 hashing. // Unfortunately, if the FIPS setting is enabled on Windows, using MD5 will throw an exception diff --git a/src/Umbraco.Core/Notifications/ContentEmptyingRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/ContentEmptyingRecycleBinNotification.cs index f66400a9a8..134e65d982 100644 --- a/src/Umbraco.Core/Notifications/ContentEmptyingRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/ContentEmptyingRecycleBinNotification.cs @@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.Notifications { public sealed class ContentEmptyingRecycleBinNotification : EmptyingRecycleBinNotification { - public ContentEmptyingRecycleBinNotification(IEnumerable deletedEntities, EventMessages messages) : base(deletedEntities, messages) + public ContentEmptyingRecycleBinNotification(IEnumerable? deletedEntities, EventMessages messages) : base(deletedEntities, messages) { } } diff --git a/src/Umbraco.Core/Notifications/EmptyingRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/EmptyingRecycleBinNotification.cs index 3d1732acfa..42005fc9f4 100644 --- a/src/Umbraco.Core/Notifications/EmptyingRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/EmptyingRecycleBinNotification.cs @@ -8,13 +8,13 @@ namespace Umbraco.Cms.Core.Notifications { public abstract class EmptyingRecycleBinNotification : StatefulNotification, ICancelableNotification where T : class { - protected EmptyingRecycleBinNotification(IEnumerable deletedEntities, EventMessages messages) + protected EmptyingRecycleBinNotification(IEnumerable? deletedEntities, EventMessages messages) { DeletedEntities = deletedEntities; Messages = messages; } - public IEnumerable DeletedEntities { get; } + public IEnumerable? DeletedEntities { get; } public EventMessages Messages { get; } diff --git a/src/Umbraco.Core/Notifications/IStatefulNotification.cs b/src/Umbraco.Core/Notifications/IStatefulNotification.cs index 7fa2382038..87d2b58cde 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/Persistence/IReadRepository.cs b/src/Umbraco.Core/Persistence/IReadRepository.cs index 57a25f3f81..0f757ae04a 100644 --- a/src/Umbraco.Core/Persistence/IReadRepository.cs +++ b/src/Umbraco.Core/Persistence/IReadRepository.cs @@ -15,7 +15,7 @@ namespace Umbraco.Cms.Core.Persistence /// /// Gets entities. /// - IEnumerable? GetMany(params TId[]? ids); + IEnumerable GetMany(params TId[]? ids); /// /// Gets a value indicating whether an entity exists. diff --git a/src/Umbraco.Core/Persistence/SqlExtensionsStatics.cs b/src/Umbraco.Core/Persistence/SqlExtensionsStatics.cs index cec65de33f..d0f32fb971 100644 --- a/src/Umbraco.Core/Persistence/SqlExtensionsStatics.cs +++ b/src/Umbraco.Core/Persistence/SqlExtensionsStatics.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.Persistence /// /// The field to alias. /// The alias. - public static object Alias(object? field, string alias) => field; + public static object? Alias(object? field, string alias) => field; /// /// Produces Sql text. diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs index 5384ef0813..ef441d3965 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs @@ -83,7 +83,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public virtual object FromDatabase(string? configurationJson, IConfigurationEditorJsonSerializer configurationEditorJsonSerializer) => string.IsNullOrWhiteSpace(configurationJson) ? new Dictionary() - : configurationEditorJsonSerializer.Deserialize>(configurationJson); + : configurationEditorJsonSerializer.Deserialize>(configurationJson)!; /// public virtual object? FromConfigurationEditor(IDictionary editorValues, object configuration) diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index 888c74ff29..ab84f7131b 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -24,16 +24,16 @@ namespace Umbraco.Cms.Core.PropertyEditors [DataContract] public class DataValueEditor : IDataValueEditor { - private readonly ILocalizedTextService? _localizedTextService; - private readonly IShortStringHelper? _shortStringHelper; + private readonly ILocalizedTextService _localizedTextService; + private readonly IShortStringHelper _shortStringHelper; private readonly IJsonSerializer? _jsonSerializer; /// /// Initializes a new instance of the class. /// public DataValueEditor( - ILocalizedTextService? localizedTextService, - IShortStringHelper? shortStringHelper, + ILocalizedTextService localizedTextService, + IShortStringHelper shortStringHelper, IJsonSerializer? jsonSerializer) // for tests, and manifest { _localizedTextService = localizedTextService; @@ -167,9 +167,9 @@ namespace Umbraco.Cms.Core.PropertyEditors // Ensure JSON is serialized properly (without indentation or converted to null when empty) if (value is not null && ValueType.InvariantEquals(ValueTypes.Json)) { - var jsonValue = _jsonSerializer.Serialize(value); + var jsonValue = _jsonSerializer?.Serialize(value); - if (jsonValue.DetectIsEmptyJson()) + if (jsonValue?.DetectIsEmptyJson() ?? false) { value = null; } @@ -231,7 +231,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// If overridden then the object returned must match the type supplied in the ValueType, otherwise persisting the /// value to the DB will fail when it tries to validate the value type. /// - public virtual object? FromEditor(ContentPropertyData editorValue, object currentValue) + public virtual object? FromEditor(ContentPropertyData editorValue, object? currentValue) { var result = TryConvertValueToCrlType(editorValue.Value); if (result.Success == false) @@ -274,7 +274,7 @@ namespace Umbraco.Cms.Core.PropertyEditors { try { - var json = _jsonSerializer.Deserialize(stringValue!); + var json = _jsonSerializer?.Deserialize(stringValue!); return json; } catch diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditorFactory.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditorFactory.cs index 300bdde672..1f717d9065 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditorFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditorFactory.cs @@ -10,9 +10,9 @@ namespace Umbraco.Cms.Core.PropertyEditors public DataValueEditorFactory(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider; - public TDataValueEditor Create(params object[] args) + public TDataValueEditor Create(params object?[] args) where TDataValueEditor: class, IDataValueEditor - => _serviceProvider.CreateInstance(args); + => _serviceProvider.CreateInstance(args.WhereNotNull()); } } diff --git a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs index 78061a1be4..5cb11b7071 100644 --- a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public class DefaultPropertyIndexValueFactory : IPropertyIndexValueFactory { /// - public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published) { yield return new KeyValuePair>( property.Alias, diff --git a/src/Umbraco.Core/PropertyEditors/MediaPicker3Configuration.cs b/src/Umbraco.Core/PropertyEditors/MediaPicker3Configuration.cs index 50595b7350..8b843fdf85 100644 --- a/src/Umbraco.Core/PropertyEditors/MediaPicker3Configuration.cs +++ b/src/Umbraco.Core/PropertyEditors/MediaPicker3Configuration.cs @@ -46,7 +46,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public class CropConfiguration { [DataMember(Name = "alias")] - public string Alias { get; set; } + public string? Alias { get; set; } [DataMember(Name = "label")] public string? Label { get; set; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/CheckboxListValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/CheckboxListValueConverter.cs index 0e89770956..2aeee98bf4 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/CheckboxListValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/CheckboxListValueConverter.cs @@ -26,7 +26,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel cacheLevel, object? source, bool preview) + public override object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel cacheLevel, object? source, bool preview) { var sourceString = source?.ToString() ?? string.Empty; diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs index c0293a0241..1da3458dab 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs @@ -71,7 +71,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return Storages.GetOrAdd(dataTypeId, id => { var dataType = _dataTypeService.GetDataType(id); - var configuration = dataType.ConfigurationAs(); + var configuration = dataType?.ConfigurationAs(); return configuration?.EnableRange ?? false; }); } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs index 2c45e5090a..da5dfd5416 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs @@ -67,7 +67,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return Storages.GetOrAdd(dataTypeId, id => { - var configuration = _dataTypeService.GetDataType(id).ConfigurationAs(); + var configuration = _dataTypeService.GetDataType(id)?.ConfigurationAs(); return configuration?.StorageType == TagsStorageType.Json; }); } diff --git a/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs b/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs index 9ea08d36d0..3c55b9d699 100644 --- a/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs +++ b/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.PublishedCache /// /// Gets the . /// - IPublishedMemberCache Members { get; } + IPublishedMemberCache? Members { get; } /// /// Gets the . diff --git a/src/Umbraco.Core/PublishedCache/PublishedElement.cs b/src/Umbraco.Core/PublishedCache/PublishedElement.cs index 1972e8a7f4..69e3d6a156 100644 --- a/src/Umbraco.Core/PublishedCache/PublishedElement.cs +++ b/src/Umbraco.Core/PublishedCache/PublishedElement.cs @@ -46,7 +46,7 @@ namespace Umbraco.Cms.Core.PublishedCache // + using an initial reference cache level of .None ensures that everything will be // cached at .Content level - and that reference cache level will propagate to all // properties - public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary values, bool previewing) + public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary values, bool previewing) : this(contentType, key, values, previewing, PropertyCacheLevel.None, null) { } diff --git a/src/Umbraco.Core/Services/ConsentService.cs b/src/Umbraco.Core/Services/ConsentService.cs index 5027df687b..bb4d989676 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 b8b4b9ed25..e48a4d2d60 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -78,7 +78,7 @@ namespace Umbraco.Cms.Core.Services IContent? content = GetById(id); // Get the version - IContent version = GetVersion(versionId); + IContent? version = GetVersion(versionId); // Good old null checks if (content == null || version == null || content.Trashed) @@ -457,9 +457,7 @@ namespace Umbraco.Cms.Core.Services { scope.ReadLock(Constants.Locks.ContentTree); IEnumerable items = _documentRepository.GetMany(idsA); - var index = items.ToDictionary(x => x.Id, x => x); - return idsA.Select(x => index.TryGetValue(x, out IContent? c) ? c : null).WhereNotNull(); } } @@ -515,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) @@ -526,11 +524,16 @@ namespace Umbraco.Cms.Core.Services using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { scope.ReadLock(Constants.Locks.ContentTree); - IEnumerable items = _documentRepository.GetMany(idsA); + IEnumerable? items = _documentRepository.GetMany(idsA); - var index = items.ToDictionary(x => x.Key, x => x); + if (items is not null) + { + var index = items.ToDictionary(x => x.Key, x => x); - return idsA.Select(x => index.TryGetValue(x, out IContent? c) ? c : null).WhereNotNull(); + return idsA.Select(x => index.TryGetValue(x, out IContent? c) ? c : null).WhereNotNull(); + } + + return null; } } @@ -565,7 +568,7 @@ namespace Umbraco.Cms.Core.Services /// public IEnumerable GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, - out long totalRecords, IQuery filter, Ordering? ordering = null) + out long totalRecords, IQuery? filter, Ordering? ordering = null) { if (pageIndex < 0) { @@ -597,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 (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -612,7 +615,7 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the version to retrieve /// An item - public IContent GetVersion(int versionId) + public IContent? GetVersion(int versionId) { using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -667,7 +670,7 @@ 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); @@ -679,7 +682,7 @@ 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) @@ -705,13 +708,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 (IScope scope = ScopeProvider.CreateScope(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); } } @@ -827,7 +830,8 @@ namespace Umbraco.Cms.Core.Services /// Parent object public IContent? GetParent(IContent? content) { - if (content?.ParentId == Constants.System.Root || content?.ParentId == Constants.System.RecycleBinContent || content is null) + if (content?.ParentId == Constants.System.Root || content?.ParentId == Constants.System.RecycleBinContent || + content is null) { return null; } @@ -839,7 +843,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 GetRootContent() + public IEnumerable? GetRootContent() { using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -853,7 +857,7 @@ namespace Umbraco.Cms.Core.Services /// Gets all published content items /// /// - internal IEnumerable GetAllPublished() + internal IEnumerable? GetAllPublished() { using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -947,7 +951,8 @@ namespace Umbraco.Cms.Core.Services #region Save, Publish, Unpublish /// - public OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, ContentScheduleCollection? contentSchedule = null) + public OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, + ContentScheduleCollection? contentSchedule = null) { PublishedState publishedState = content.PublishedState; if (publishedState != PublishedState.Published && publishedState != PublishedState.Unpublished) @@ -1010,10 +1015,14 @@ namespace Umbraco.Cms.Core.Services if (culturesChanging != null) { - var langs = string.Join(", ", _languageRepository.GetMany() + var languages = _languageRepository.GetMany()? .Where(x => culturesChanging.InvariantContains(x.IsoCode)) - .Select(x => x.CultureName)); - Audit(AuditType.SaveVariant, userId, content.Id, $"Saved languages: {langs}", langs); + .Select(x => x.CultureName); + if (languages is not null) + { + var langs = string.Join(", ", languages); + Audit(AuditType.SaveVariant, userId, content.Id, $"Saved languages: {langs}", langs); + } } else { @@ -1808,7 +1817,7 @@ namespace Umbraco.Cms.Core.Services contentSchedule.Clear(culture, ContentScheduleAction.Release, date); if (d.Trashed) - { + { continue; // won't publish } @@ -1827,7 +1836,7 @@ namespace Umbraco.Cms.Core.Services publishing &= tryPublish; //set the culture to be published if (!publishing) - { + { continue; } } @@ -1993,7 +2002,7 @@ namespace Umbraco.Cms.Core.Services // if not published, publish if force/root else do nothing return force || isRoot - ? new HashSet { "*" } // "*" means 'publish all' + ? new HashSet {"*"} // "*" means 'publish all' : null; // null means 'nothing to do' } @@ -2321,8 +2330,8 @@ namespace Umbraco.Cms.Core.Services if (deletePriorVersions) { - IContent content = GetVersion(versionId); - DeleteVersions(id, content.UpdateDate, userId); + IContent? content = GetVersion(versionId); + DeleteVersions(id, content?.UpdateDate ?? DateTime.Now, userId); } scope.WriteLock(Constants.Locks.ContentTree); @@ -2549,7 +2558,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)) @@ -2558,10 +2567,13 @@ namespace Umbraco.Cms.Core.Services return OperationResult.Cancel(eventMessages); } - foreach (IContent content in contents) + if (contents is not null) { - DeleteLocked(scope, content, eventMessages); - deleted.Add(content); + foreach (IContent content in contents) + { + DeleteLocked(scope, content, eventMessages); + deleted.Add(content); + } } scope.Notifications.Publish( @@ -2665,7 +2677,7 @@ namespace Umbraco.Cms.Core.Services // keep track of copies copies.Add(Tuple.Create(content, copy)); - var idmap = new Dictionary { [content.Id] = copy.Id }; + var idmap = new Dictionary {[content.Id] = copy.Id}; if (recursive) // process descendants { @@ -2965,19 +2977,22 @@ 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 // these must be filtered out here - var parents = new List { content.Id }; - foreach (IContent c in contents) + var parents = new List {content.Id}; + if (contents is not null) { - if (parents.Contains(c.ParentId)) + foreach (IContent c in contents) { - yield return c; - parents.Add(c.Id); + if (parents.Contains(c.ParentId)) + { + yield return c; + parents.Add(c.Id); + } } } } @@ -2986,12 +3001,13 @@ namespace Umbraco.Cms.Core.Services #region Private Methods - private void Audit(AuditType type, int userId, int objectId, string? message = null, string? parameters = null) => + private void Audit(AuditType type, int userId, int objectId, string? message = null, + string? parameters = null) => _auditRepository.Save(new AuditItem(objectId, type, userId, UmbracoObjectTypes.Document.GetName(), message, parameters)); - private bool IsDefaultCulture(IReadOnlyCollection langs, string culture) => - langs.Any(x => x.IsDefault && x.IsoCode.InvariantEquals(culture)); + private bool IsDefaultCulture(IReadOnlyCollection? langs, string culture) => + langs?.Any(x => x.IsDefault && x.IsoCode.InvariantEquals(culture)) ?? false; private bool IsMandatoryCulture(IReadOnlyCollection langs, string culture) => langs.Any(x => x.IsMandatory && x.IsoCode.InvariantEquals(culture)); @@ -3029,7 +3045,7 @@ namespace Umbraco.Cms.Core.Services var variesByCulture = content.ContentType.VariesByCulture(); CultureImpact[] impactsToPublish = culturesPublishing == null - ? new[] { CultureImpact.Invariant } //if it's null it's invariant + ? new[] {CultureImpact.Invariant} //if it's null it's invariant : culturesPublishing.Select(x => CultureImpact.Explicit(x, allLangs.Any(lang => lang.IsoCode.InvariantEquals(x) && lang.IsMandatory))).ToArray(); @@ -3096,7 +3112,7 @@ namespace Umbraco.Cms.Core.Services ContentScheduleCollection contentSchedule = _documentRepository.GetContentSchedule(content.Id); //loop over each culture publishing - or string.Empty for invariant - foreach (var culture in culturesPublishing ?? new[] { string.Empty }) + foreach (var culture in culturesPublishing ?? new[] {string.Empty}) { // ensure that the document status is correct // note: culture will be string.Empty for invariant @@ -3334,7 +3350,12 @@ 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) + { + return; + } if (scope.Notifications.PublishCancelable(new ContentDeletingNotification(contents, eventMessages))) { @@ -3357,12 +3378,15 @@ 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); - foreach (IContent child in children) + IEnumerable? children = _documentRepository.Get(childQuery); + if (children is not null) { - // see MoveToRecycleBin - PerformMoveLocked(child, Constants.System.RecycleBinContent, null, userId, moves, true); - changes.Add(new TreeChange(content, TreeChangeTypes.RefreshBranch)); + foreach (IContent child in children) + { + // see MoveToRecycleBin + PerformMoveLocked(child, Constants.System.RecycleBinContent, null, userId, moves, true); + changes.Add(new TreeChange(content, TreeChangeTypes.RefreshBranch)); + } } // delete content @@ -3395,7 +3419,7 @@ namespace Umbraco.Cms.Core.Services /// Id of the /// Optional id of the user deleting the media public void DeleteOfType(int contentTypeId, int userId = Constants.Security.SuperUserId) => - DeleteOfTypes(new[] { contentTypeId }, userId); + DeleteOfTypes(new[] {contentTypeId}, userId); private IContentType GetContentType(IScope scope, string contentTypeAlias) { @@ -3413,7 +3437,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) { @@ -3524,7 +3548,7 @@ namespace Umbraco.Cms.Core.Services } } - private static readonly string?[] ArrayOfOneNullString = { null }; + private static readonly string?[] ArrayOfOneNullString = {null}; public IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = Constants.Security.SuperUserId) @@ -3575,7 +3599,7 @@ namespace Umbraco.Cms.Core.Services return content; } - public IEnumerable GetBlueprintsForContentTypes(params int[] contentTypeId) + public IEnumerable? GetBlueprintsForContentTypes(params int[] contentTypeId) { using (ScopeProvider.CreateScope(autoComplete: true)) { @@ -3585,7 +3609,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; @@ -3609,24 +3633,27 @@ namespace Umbraco.Cms.Core.Services query.Where(x => contentTypeIdsA.Contains(x.ContentTypeId)); } - IContent[] blueprints = _documentBlueprintRepository.Get(query).Select(x => + IContent[]? blueprints = _documentBlueprintRepository.Get(query)?.Select(x => { x.Blueprint = true; return x; }).ToArray(); - foreach (IContent blueprint in blueprints) + if (blueprints is not null) { - _documentBlueprintRepository.Delete(blueprint); - } + foreach (IContent blueprint in blueprints) + { + _documentBlueprintRepository.Delete(blueprint); + } - scope.Notifications.Publish(new ContentDeletedBlueprintNotification(blueprints, evtMsgs)); - scope.Complete(); + scope.Notifications.Publish(new ContentDeletedBlueprintNotification(blueprints, evtMsgs)); + scope.Complete(); + } } } public void DeleteBlueprintsOfType(int contentTypeId, int userId = Constants.Security.SuperUserId) => - DeleteBlueprintsOfTypes(new[] { contentTypeId }, userId); + DeleteBlueprintsOfTypes(new[] {contentTypeId}, userId); #endregion } diff --git a/src/Umbraco.Core/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs index 1b9d9498f7..b3cb16e5f5 100644 --- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs @@ -57,7 +57,7 @@ namespace Umbraco.Extensions } #endregion - public static IEnumerable GetByIds(this IContentService contentService, IEnumerable ids) + public static IEnumerable? GetByIds(this IContentService contentService, IEnumerable ids) { var guids = new List(); foreach (var udi in ids) diff --git a/src/Umbraco.Core/Services/ContentVersionService.cs b/src/Umbraco.Core/Services/ContentVersionService.cs index d2b50cc82a..aa278324eb 100644 --- a/src/Umbraco.Core/Services/ContentVersionService.cs +++ b/src/Umbraco.Core/Services/ContentVersionService.cs @@ -80,8 +80,12 @@ namespace Umbraco.Cms.Core.Services */ using (IScope scope = _scopeProvider.CreateScope(autoComplete: true)) { - IReadOnlyCollection allHistoricVersions = _documentVersionRepository.GetDocumentVersionsEligibleForCleanup(); + IReadOnlyCollection? allHistoricVersions = _documentVersionRepository.GetDocumentVersionsEligibleForCleanup(); + if (allHistoricVersions is null) + { + return Array.Empty(); + } _logger.LogDebug("Discovered {count} candidate(s) for ContentVersion cleanup", allHistoricVersions.Count); versionsToDelete = new List(allHistoricVersions.Count); @@ -135,7 +139,7 @@ namespace Umbraco.Cms.Core.Services } /// - public IEnumerable GetPagedContentVersions(int contentId, long pageIndex, int pageSize, out long totalRecords, string? culture = null) + public IEnumerable? GetPagedContentVersions(int contentId, long pageIndex, int pageSize, out long totalRecords, string? culture = null) { if (pageIndex < 0) { @@ -163,7 +167,12 @@ namespace Umbraco.Cms.Core.Services scope.WriteLock(Constants.Locks.ContentTree); _documentVersionRepository.SetPreventCleanup(versionId, preventCleanup); - ContentVersionMeta version = _documentVersionRepository.Get(versionId); + ContentVersionMeta? version = _documentVersionRepository.Get(versionId); + + if (version is null) + { + return; + } AuditType auditType = preventCleanup ? AuditType.ContentVersionPreventCleanup diff --git a/src/Umbraco.Core/Services/EntityService.cs b/src/Umbraco.Core/Services/EntityService.cs index b971019be6..69f705ffee 100644 --- a/src/Umbraco.Core/Services/EntityService.cs +++ b/src/Umbraco.Core/Services/EntityService.cs @@ -55,7 +55,7 @@ namespace Umbraco.Cms.Core.Services } /// - public IEntitySlim Get(int id) + public IEntitySlim? Get(int id) { using (ScopeProvider.CreateScope(autoComplete: true)) { @@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.Services } /// - public IEntitySlim Get(Guid key) + public IEntitySlim? Get(Guid key) { using (ScopeProvider.CreateScope(autoComplete: true)) { @@ -73,7 +73,7 @@ namespace Umbraco.Cms.Core.Services } /// - public virtual IEntitySlim Get(int id, UmbracoObjectTypes objectType) + public virtual IEntitySlim? Get(int id, UmbracoObjectTypes objectType) { using (ScopeProvider.CreateScope(autoComplete: true)) { @@ -82,7 +82,7 @@ namespace Umbraco.Cms.Core.Services } /// - public IEntitySlim Get(Guid key, UmbracoObjectTypes objectType) + public IEntitySlim? Get(Guid key, UmbracoObjectTypes objectType) { using (ScopeProvider.CreateScope(autoComplete: true)) { @@ -91,7 +91,7 @@ namespace Umbraco.Cms.Core.Services } /// - public virtual IEntitySlim Get(int id) + public virtual IEntitySlim? Get(int id) where T : IUmbracoEntity { using (ScopeProvider.CreateScope(autoComplete: true)) @@ -101,7 +101,7 @@ namespace Umbraco.Cms.Core.Services } /// - public virtual IEntitySlim Get(Guid key) + public virtual IEntitySlim? Get(Guid key) where T : IUmbracoEntity { using (ScopeProvider.CreateScope(autoComplete: true)) @@ -235,7 +235,7 @@ namespace Umbraco.Cms.Core.Services using (ScopeProvider.CreateScope(autoComplete: true)) { var entity = _entityRepository.Get(id); - if (entity.ParentId == -1 || entity.ParentId == -20 || entity.ParentId == -21) + if (entity is null || entity.ParentId == -1 || entity.ParentId == -20 || entity.ParentId == -21) return null; return _entityRepository.Get(entity.ParentId); } @@ -247,7 +247,7 @@ namespace Umbraco.Cms.Core.Services using (ScopeProvider.CreateScope(autoComplete: true)) { var entity = _entityRepository.Get(id); - if (entity.ParentId == -1 || entity.ParentId == -20 || entity.ParentId == -21) + if (entity is null || entity.ParentId == -1 || entity.ParentId == -20 || entity.ParentId == -21) return null; return _entityRepository.Get(entity.ParentId, objectType.GetGuid()); } @@ -279,7 +279,7 @@ namespace Umbraco.Cms.Core.Services using (ScopeProvider.CreateScope(autoComplete: true)) { var entity = _entityRepository.Get(id); - var pathMatch = entity.Path + ","; + var pathMatch = entity?.Path + ","; var query = Query().Where(x => x.Path.StartsWith(pathMatch) && x.Id != id); return _entityRepository.GetByQuery(query); } @@ -291,6 +291,10 @@ namespace Umbraco.Cms.Core.Services using (ScopeProvider.CreateScope(autoComplete: true)) { var entity = _entityRepository.Get(id); + if (entity is null) + { + return Enumerable.Empty(); + } var query = Query().Where(x => x.Path.StartsWith(entity.Path) && x.Id != id); return _entityRepository.GetByQuery(query, objectType.GetGuid()); } diff --git a/src/Umbraco.Core/Services/ExternalLoginService.cs b/src/Umbraco.Core/Services/ExternalLoginService.cs index 291464f16f..1e8d25b8e8 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.CreateScope(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.CreateScope(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.CreateScope(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/IConsentService.cs b/src/Umbraco.Core/Services/IConsentService.cs index 1833090501..50222a7f28 100644 --- a/src/Umbraco.Core/Services/IConsentService.cs +++ b/src/Umbraco.Core/Services/IConsentService.cs @@ -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 35fdb1f4d9..e53f091c49 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. @@ -84,17 +84,17 @@ namespace Umbraco.Cms.Core.Services /// /// Gets documents. /// - IEnumerable GetByIds(IEnumerable ids); + IEnumerable? GetByIds(IEnumerable ids); /// /// 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. @@ -137,12 +137,12 @@ namespace Umbraco.Cms.Core.Services /// /// Gets a version of a document. /// - IContent GetVersion(int versionId); + IContent? GetVersion(int versionId); /// /// Gets root-level documents. /// - IEnumerable GetRootContent(); + IEnumerable? GetRootContent(); /// /// Gets documents having an expiration date before (lower than, or equal to) a specified date. diff --git a/src/Umbraco.Core/Services/IContentVersionService.cs b/src/Umbraco.Core/Services/IContentVersionService.cs index 84b71213ff..d0f203b2ef 100644 --- a/src/Umbraco.Core/Services/IContentVersionService.cs +++ b/src/Umbraco.Core/Services/IContentVersionService.cs @@ -15,7 +15,7 @@ namespace Umbraco.Cms.Core.Services /// Gets paginated content versions for given content id paginated. /// /// Thrown when is invalid. - IEnumerable GetPagedContentVersions(int contentId, long pageIndex, int pageSize, out long totalRecords, string? culture = null); + IEnumerable? GetPagedContentVersions(int contentId, long pageIndex, int pageSize, out long totalRecords, string? culture = null); /// /// Updates preventCleanup value for given content version. diff --git a/src/Umbraco.Core/Services/IEntityService.cs b/src/Umbraco.Core/Services/IEntityService.cs index cb72735c02..66298aba1d 100644 --- a/src/Umbraco.Core/Services/IEntityService.cs +++ b/src/Umbraco.Core/Services/IEntityService.cs @@ -12,41 +12,41 @@ namespace Umbraco.Cms.Core.Services /// Gets an entity. /// /// The identifier of the entity. - IEntitySlim Get(int id); + IEntitySlim? Get(int id); /// /// Gets an entity. /// /// The unique key of the entity. - IEntitySlim Get(Guid key); + IEntitySlim? Get(Guid key); /// /// Gets an entity. /// /// The identifier of the entity. /// The object type of the entity. - IEntitySlim Get(int id, UmbracoObjectTypes objectType); + IEntitySlim? Get(int id, UmbracoObjectTypes objectType); /// /// Gets an entity. /// /// The unique key of the entity. /// The object type of the entity. - IEntitySlim Get(Guid key, UmbracoObjectTypes objectType); + IEntitySlim? Get(Guid key, UmbracoObjectTypes objectType); /// /// Gets an entity. /// /// The type used to determine the object type of the entity. /// The identifier of the entity. - IEntitySlim Get(int id) where T : IUmbracoEntity; + IEntitySlim? Get(int id) where T : IUmbracoEntity; /// /// Gets an entity. /// /// The type used to determine the object type of the entity. /// The unique key of the entity. - IEntitySlim Get(Guid key) where T : IUmbracoEntity; + IEntitySlim? Get(Guid key) where T : IUmbracoEntity; /// /// Determines whether an entity exists. diff --git a/src/Umbraco.Core/Services/IExternalLoginService.cs b/src/Umbraco.Core/Services/IExternalLoginService.cs index 75f8069f0c..05f131919e 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 bc31f54f8b..1b378491c0 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/IMembershipMemberService.cs b/src/Umbraco.Core/Services/IMembershipMemberService.cs index 48900752e2..f183882b55 100644 --- a/src/Umbraco.Core/Services/IMembershipMemberService.cs +++ b/src/Umbraco.Core/Services/IMembershipMemberService.cs @@ -99,7 +99,7 @@ namespace Umbraco.Cms.Core.Services /// An can be of type or /// Username to use for retrieval /// - T GetByUsername(string username); + T? GetByUsername(string username); /// /// Deletes an diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs index ee16ef64a6..3149ad0370 100644 --- a/src/Umbraco.Core/Services/IUserService.cs +++ b/src/Umbraco.Core/Services/IUserService.cs @@ -106,7 +106,7 @@ namespace Umbraco.Cms.Core.Services /// /// Username /// - IProfile GetProfileByUserName(string username); + IProfile? GetProfileByUserName(string username); /// /// Gets a user by Id diff --git a/src/Umbraco.Core/Services/PropertyValidationService.cs b/src/Umbraco.Core/Services/PropertyValidationService.cs index 7aea02ca57..c5a4312776 100644 --- a/src/Umbraco.Core/Services/PropertyValidationService.cs +++ b/src/Umbraco.Core/Services/PropertyValidationService.cs @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.Services /// public IEnumerable ValidatePropertyValue( IPropertyType propertyType, - object postedValue) + object? postedValue) { if (propertyType is null) throw new ArgumentNullException(nameof(propertyType)); var dataType = _dataTypeService.GetDataType(propertyType.DataTypeId); @@ -47,7 +47,7 @@ namespace Umbraco.Cms.Core.Services public IEnumerable ValidatePropertyValue( IDataEditor editor, IDataType dataType, - object postedValue, + object? postedValue, bool isRequired, string? validationRegExp, string? isRequiredMessage, @@ -190,7 +190,7 @@ namespace Umbraco.Cms.Core.Services // the property will be displayed as a label, so flagging it as invalid would be pointless. return true; } - var configuration = _dataTypeService.GetDataType(propertyType.DataTypeId).Configuration; + var configuration = _dataTypeService.GetDataType(propertyType.DataTypeId)?.Configuration; var valueEditor = editor.GetValueEditor(configuration); return !valueEditor.Validate(value, propertyType.Mandatory, propertyType.ValidationRegExp).Any(); } diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index d3b52701bc..a6bad5b2fe 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -183,7 +183,7 @@ namespace Umbraco.Cms.Core.Services using (var scope = ScopeProvider.CreateScope(autoComplete: true)) { var query = Query().Where(x => x.Email.Equals(email)); - return _userRepository.Get(query).FirstOrDefault(); + return _userRepository.Get(query)?.FirstOrDefault(); } } @@ -192,7 +192,7 @@ namespace Umbraco.Cms.Core.Services /// /// Username to use for retrieval /// - public IUser GetByUsername(string username) + public IUser? GetByUsername(string username) { using (var scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -649,7 +649,7 @@ namespace Umbraco.Cms.Core.Services /// /// Username /// - public IProfile GetProfileByUserName(string username) + public IProfile? GetProfileByUserName(string username) { using (var scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -770,7 +770,7 @@ namespace Umbraco.Cms.Core.Services { var query = Query().Where(x => aliases.SqlIn(x.Alias)); var contents = _userGroupRepository.Get(query); - return contents.WhereNotNull().ToArray(); + return contents?.WhereNotNull().ToArray() ?? Enumerable.Empty(); } } @@ -787,7 +787,7 @@ namespace Umbraco.Cms.Core.Services { var query = Query().Where(x => x.Alias == alias); var contents = _userGroupRepository.Get(query); - return contents.FirstOrDefault(); + return contents?.FirstOrDefault(); } } diff --git a/src/Umbraco.Core/Sync/RefreshInstruction.cs b/src/Umbraco.Core/Sync/RefreshInstruction.cs index 169b58f5a1..b8609410ab 100644 --- a/src/Umbraco.Core/Sync/RefreshInstruction.cs +++ b/src/Umbraco.Core/Sync/RefreshInstruction.cs @@ -106,12 +106,12 @@ namespace Umbraco.Cms.Core.Sync if (idType == typeof(int)) { // Bulk of ints is supported - var intIds = ids.Cast().ToArray(); - return new[] { new RefreshInstruction(refresher, RefreshMethodType.RefreshByIds, jsonSerializer.Serialize(intIds), intIds.Length) }; + var intIds = ids?.Cast().ToArray(); + return new[] { new RefreshInstruction(refresher, RefreshMethodType.RefreshByIds, jsonSerializer.Serialize(intIds), intIds?.Length ?? 0) }; } // Else must be guids, bulk of guids is not supported, so iterate. - return ids.Select(x => new RefreshInstruction(refresher, RefreshMethodType.RefreshByGuid, (Guid) x)); + return ids?.Select(x => new RefreshInstruction(refresher, RefreshMethodType.RefreshByGuid, (Guid) x)) ?? Enumerable.Empty(); case MessageType.RemoveById: if (idType == null) @@ -120,7 +120,7 @@ namespace Umbraco.Cms.Core.Sync } // Must be ints, bulk-remove is not supported, so iterate. - return ids.Select(x => new RefreshInstruction(refresher, RefreshMethodType.RemoveById, (int) x)); + return ids?.Select(x => new RefreshInstruction(refresher, RefreshMethodType.RemoveById, (int) x)) ?? Enumerable.Empty(); //return new[] { new RefreshInstruction(refresher, RefreshMethodType.RemoveByIds, JsonConvert.SerializeObject(ids.Cast().ToArray())) }; default: diff --git a/src/Umbraco.Core/Trees/TreeNode.cs b/src/Umbraco.Core/Trees/TreeNode.cs index ccf5a38347..ba856b6d3a 100644 --- a/src/Umbraco.Core/Trees/TreeNode.cs +++ b/src/Umbraco.Core/Trees/TreeNode.cs @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Trees } [DataMember(Name = "parentId", IsRequired = true)] - public new object ParentId { get; set; } + public new object? ParentId { get; set; } /// /// A flag to set whether or not this node has children diff --git a/src/Umbraco.Core/Udi.cs b/src/Umbraco.Core/Udi.cs index 55efc549eb..c18bed7a90 100644 --- a/src/Umbraco.Core/Udi.cs +++ b/src/Umbraco.Core/Udi.cs @@ -157,7 +157,7 @@ namespace Umbraco.Cms.Core public static bool operator ==(Udi? udi1, Udi? udi2) { if (ReferenceEquals(udi1, udi2)) return true; - if ((object)udi1 == null || (object)udi2 == null) return false; + if ((object?)udi1 == null || (object?)udi2 == null) return false; return udi1.Equals(udi2); } diff --git a/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs b/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs index 033206a453..94710429f0 100644 --- a/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs +++ b/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Umbraco.Cms.Core.Cache; namespace Umbraco.Cms.Core.Web @@ -17,7 +18,7 @@ namespace Umbraco.Cms.Core.Web /// /// Tries to get the object. /// - public bool TryGetUmbracoContext(out IUmbracoContext? umbracoContext) + public bool TryGetUmbracoContext([MaybeNullWhen(false)] out IUmbracoContext umbracoContext) { umbracoContext = Value; diff --git a/src/Umbraco.Infrastructure/Install/InstallSteps/DatabaseUpgradeStep.cs b/src/Umbraco.Infrastructure/Install/InstallSteps/DatabaseUpgradeStep.cs index 693cd1cbde..c0e272a6aa 100644 --- a/src/Umbraco.Infrastructure/Install/InstallSteps/DatabaseUpgradeStep.cs +++ b/src/Umbraco.Infrastructure/Install/InstallSteps/DatabaseUpgradeStep.cs @@ -55,7 +55,7 @@ namespace Umbraco.Cms.Infrastructure.Install.InstallSteps var result = _databaseBuilder.UpgradeSchemaAndData(plan); - if (result.Success == false) + if (result?.Success == false) { throw new InstallException("The database failed to upgrade. ERROR: " + result.Message); } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Controllers/ContentControllerTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Controllers/ContentControllerTests.cs index b91e87907a..ec5968e92d 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Controllers/ContentControllerTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/Controllers/ContentControllerTests.cs @@ -529,6 +529,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.BackOffice.Controllers var url = PrepareApiControllerUrl(x => x.PostSave(null)); + var result = JsonConvert.SerializeObject(model); HttpResponseMessage response = await Client.PostAsync(url, new MultipartFormDataContent { { new StringContent(JsonConvert.SerializeObject(model)), "contentItem" }