From b75eae01f3ac347f27b5c0a22bf9161b09e051e5 Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Date: Wed, 9 Feb 2022 13:24:35 +0100 Subject: [PATCH] Add nullability to core project --- src/Umbraco.Core/AttemptOfTResult.cs | 6 +- src/Umbraco.Core/AttemptOfTResultTStatus.cs | 20 +-- .../Cache/DataTypeCacheRefresher.cs | 2 +- src/Umbraco.Core/Cache/MacroCacheRefresher.cs | 2 +- src/Umbraco.Core/Cache/MediaCacheRefresher.cs | 2 +- .../Cache/MemberCacheRefresher.cs | 2 +- .../Cache/RelationTypeCacheRefresher.cs | 4 +- src/Umbraco.Core/Cache/UserCacheRefresher.cs | 2 +- .../Cache/UserGroupCacheRefresher.cs | 4 +- .../Configuration/Grid/IGridEditorConfig.cs | 10 +- .../Configuration/IUmbracoVersion.cs | 2 +- .../Configuration/UmbracoVersion.cs | 2 +- .../CustomBooleanTypeConverter.cs | 4 +- .../DefaultEventMessagesFactory.cs | 2 +- src/Umbraco.Core/DelegateEqualityComparer.cs | 8 +- .../Events/EventAggregator.Notifications.cs | 30 +++- src/Umbraco.Core/Events/EventAggregator.cs | 2 +- src/Umbraco.Core/Events/IEventAggregator.cs | 2 +- .../Events/IEventMessagesAccessor.cs | 2 +- src/Umbraco.Core/ExpressionHelper.cs | 40 ++--- .../Extensions/ContentExtensions.cs | 18 +- .../Extensions/DelegateExtensions.cs | 4 +- .../Extensions/EnumerableExtensions.cs | 4 +- .../NameValueCollectionExtensions.cs | 2 +- .../Extensions/ObjectExtensions.cs | 10 +- .../Extensions/PublishedPropertyExtension.cs | 4 +- .../PublishedSnapshotAccessorExtensions.cs | 2 +- .../Extensions/StringExtensions.cs | 4 +- .../UmbracoContextAccessorExtensions.cs | 2 +- src/Umbraco.Core/Extensions/XmlExtensions.cs | 6 +- src/Umbraco.Core/HybridAccessorBase.cs | 2 +- .../HybridEventMessagesAccessor.cs | 2 +- src/Umbraco.Core/IO/MediaFileManager.cs | 2 +- src/Umbraco.Core/LambdaExpressionCacheKey.cs | 12 +- src/Umbraco.Core/Macros/IMacroRenderer.cs | 2 +- .../Media/Exif/ExifExtendedProperty.cs | 3 +- src/Umbraco.Core/Models/Content.cs | 4 +- src/Umbraco.Core/Models/ContentBase.cs | 14 +- .../Models/ContentBaseExtensions.cs | 4 +- .../ContentEditing/ContentPropertyDisplay.cs | 4 +- .../ContentEditing/ContentPropertyDto.cs | 2 +- .../DataTypeConfigurationFieldDisplay.cs | 8 +- .../DataTypeConfigurationFieldSave.cs | 4 +- .../Models/ContentEditing/MacroParameter.cs | 6 +- .../ContentEditing/PropertyEditorBasic.cs | 6 +- .../ContentEditing/PropertyGroupBasic.cs | 2 +- .../PropertyGroupBasicExtensions.cs | 2 +- .../Models/ContentRepositoryExtensions.cs | 35 +++- src/Umbraco.Core/Models/DataType.cs | 20 +-- .../Models/Entities/EntityBase.cs | 2 +- src/Umbraco.Core/Models/IContentBase.cs | 2 +- src/Umbraco.Core/Models/IDataType.cs | 2 +- src/Umbraco.Core/Models/IDataValueEditor.cs | 6 +- src/Umbraco.Core/Models/IDomain.cs | 2 +- src/Umbraco.Core/Models/IMediaUrlGenerator.cs | 2 +- src/Umbraco.Core/Models/IProperty.cs | 2 +- .../Models/IPropertyCollection.cs | 6 +- .../Mapping/ContentPropertyBasicMapper.cs | 8 +- .../Mapping/ContentPropertyDisplayMapper.cs | 16 +- .../Mapping/ContentPropertyDtoMapper.cs | 16 +- .../Models/Mapping/DataTypeMapDefinition.cs | 14 +- .../Models/Mapping/MacroMapDefinition.cs | 6 +- .../Mapping/MemberTabsAndPropertiesMapper.cs | 6 +- .../Models/Mapping/PropertyTypeGroupMapper.cs | 2 +- .../Models/Mapping/TabsAndPropertiesMapper.cs | 2 +- src/Umbraco.Core/Models/Member.cs | 66 +++---- .../Models/Membership/UserProfile.cs | 4 +- .../Models/PartialViewMacroModelExtensions.cs | 2 +- src/Umbraco.Core/Models/Property.cs | 14 +- src/Umbraco.Core/Models/PropertyCollection.cs | 23 ++- src/Umbraco.Core/Models/PropertyGroup.cs | 28 +-- .../Models/PropertyGroupCollection.cs | 4 +- .../Models/PropertyGroupExtensions.cs | 14 +- .../Models/PropertyTagsExtensions.cs | 18 +- src/Umbraco.Core/Models/PropertyType.cs | 53 +++--- .../Models/PropertyTypeCollection.cs | 13 +- .../PublishedContent/IPublishedElement.cs | 4 +- .../IPublishedModelFactory.cs | 2 +- .../IPublishedPropertyType.cs | 8 +- .../PublishedContentWrapped.cs | 4 +- .../PublishedElementWrapped.cs | 4 +- .../PublishedContent/PublishedModelFactory.cs | 5 +- .../PublishedContent/PublishedPropertyType.cs | 8 +- .../PublishedValueFallback.cs | 14 +- .../PublishedContent/RawValueProperty.cs | 8 +- src/Umbraco.Core/Models/RelationType.cs | 2 +- src/Umbraco.Core/Models/Stylesheet.cs | 2 +- src/Umbraco.Core/Models/UmbracoDomain.cs | 4 +- .../Models/UmbracoUserExtensions.cs | 4 +- .../Models/UpgradeCheckResponse.cs | 8 +- src/Umbraco.Core/Models/UserExtensions.cs | 26 ++- src/Umbraco.Core/NamedUdiRange.cs | 2 +- .../PropertyEditors/ConfigurationEditor.cs | 13 +- .../PropertyEditors/ConfigurationField.cs | 16 +- .../ConfigurationFieldAttribute.cs | 12 +- .../PropertyEditors/DataEditor.cs | 26 ++- .../PropertyEditors/DataEditorAttribute.cs | 2 +- .../PropertyEditors/DataValueEditor.cs | 22 +-- .../DataValueReferenceFactoryCollection.cs | 2 +- .../PropertyEditors/DateValueEditor.cs | 2 +- .../DefaultPropertyIndexValueFactory.cs | 4 +- .../PropertyEditors/GridEditor.cs | 13 +- .../PropertyEditors/IConfigurationEditor.cs | 4 +- .../PropertyEditors/IDataEditor.cs | 4 +- .../PropertyEditors/IDataValueReference.cs | 2 +- .../IDataValueReferenceFactory.cs | 2 +- .../IPropertyIndexValueFactory.cs | 2 +- .../IPropertyValueConverter.cs | 8 +- .../PropertyEditors/IValueFormatValidator.cs | 2 +- .../PropertyEditors/IValueValidator.cs | 2 +- .../PropertyEditors/ListViewConfiguration.cs | 16 +- .../ManifestValueValidatorCollection.cs | 4 +- .../MediaUrlGeneratorCollection.cs | 2 +- .../PropertyEditors/MissingPropertyEditor.cs | 2 +- .../ParameterEditorCollection.cs | 4 +- .../PropertyCacheCompression.cs | 2 +- .../PropertyEditorCollection.cs | 4 +- .../PropertyEditorTagsExtensions.cs | 2 +- .../PropertyValueConverterBase.cs | 8 +- .../PropertyValueConverterCollection.cs | 4 +- .../TagsPropertyEditorAttribute.cs | 2 +- .../PropertyEditors/TextOnlyValueEditor.cs | 2 +- .../TextStringValueConverter.cs | 8 +- .../Validators/DateTimeValidator.cs | 2 +- .../Validators/DecimalValidator.cs | 2 +- .../Validators/DelimitedValueValidator.cs | 10 +- .../Validators/EmailValidator.cs | 2 +- .../Validators/IntegerValidator.cs | 2 +- .../Validators/RegexValidator.cs | 8 +- .../Validators/RequiredValidator.cs | 4 +- .../CheckboxListValueConverter.cs | 2 +- .../ContentPickerValueConverter.cs | 14 +- .../DatePickerValueConverter.cs | 8 +- .../ValueConverters/DecimalValueConverter.cs | 2 +- .../EmailAddressValueConverter.cs | 2 +- .../EyeDropperValueConverter.cs | 2 +- .../ValueConverters/IntegerValueConverter.cs | 2 +- .../ValueConverters/LabelValueConverter.cs | 6 +- .../MediaPickerValueConverter.cs | 22 +-- .../MemberGroupPickerValueConverter.cs | 2 +- .../MemberPickerValueConverter.cs | 12 +- .../MultiNodeTreePickerValueConverter.cs | 20 +-- .../MultipleTextStringValueConverter.cs | 17 +- .../MustBeStringValueConverter.cs | 2 +- .../RadioButtonListValueConverter.cs | 2 +- .../SimpleTinyMceValueConverter.cs | 6 +- .../ValueConverters/SliderValueConverter.cs | 8 +- .../ValueConverters/TagsValueConverter.cs | 12 +- .../UploadPropertyConverter.cs | 2 +- .../ValueConverters/YesNoValueConverter.cs | 6 +- .../PropertyEditors/ValueTypes.cs | 6 +- .../PropertyEditors/VoidEditor.cs | 2 +- .../PublishedCache/IPublishedCache.cs | 2 +- .../PublishedCache/IPublishedSnapshot.cs | 2 +- .../IPublishedSnapshotAccessor.cs | 2 +- .../IPublishedSnapshotService.cs | 6 +- src/Umbraco.Core/PublishedCache/ITagQuery.cs | 16 +- .../Internal/InternalPublishedContent.cs | 14 +- .../PublishedCache/PublishedCacheBase.cs | 6 +- .../PublishedCache/PublishedElement.cs | 12 +- .../PublishedElementPropertyBase.cs | 48 ++--- ...UmbracoContextPublishedSnapshotAccessor.cs | 8 +- src/Umbraco.Core/ReflectionUtilities.cs | 39 ++-- src/Umbraco.Core/Routing/AliasUrlProvider.cs | 4 +- .../Routing/ContentFinderByIdPath.cs | 4 +- .../Routing/ContentFinderByPageIdQuery.cs | 2 +- .../Routing/ContentFinderByRedirectUrl.cs | 4 +- .../Routing/ContentFinderByUrl.cs | 6 +- .../Routing/ContentFinderByUrlAlias.cs | 14 +- .../Routing/ContentFinderByUrlAndTemplate.cs | 2 +- .../Routing/DefaultMediaUrlProvider.cs | 10 +- .../Routing/DefaultUrlProvider.cs | 16 +- src/Umbraco.Core/Routing/DomainUtilities.cs | 26 +-- src/Umbraco.Core/Routing/IMediaUrlProvider.cs | 2 +- src/Umbraco.Core/Routing/IPublishedRequest.cs | 14 +- .../Routing/IPublishedRequestBuilder.cs | 12 +- .../Routing/IPublishedUrlProvider.cs | 10 +- src/Umbraco.Core/Routing/ISiteDomainMapper.cs | 4 +- src/Umbraco.Core/Routing/IUrlProvider.cs | 2 +- src/Umbraco.Core/Routing/PublishedRequest.cs | 16 +- .../Routing/PublishedRequestBuilder.cs | 20 +-- .../Routing/PublishedRequestExtensions.cs | 2 +- .../Routing/PublishedRequestOld.cs | 24 +-- src/Umbraco.Core/Routing/PublishedRouter.cs | 40 ++--- .../Routing/RouteRequestOptions.cs | 2 +- src/Umbraco.Core/Routing/SiteDomainMapper.cs | 34 ++-- src/Umbraco.Core/Routing/UrlInfo.cs | 8 +- src/Umbraco.Core/Routing/UrlProvider.cs | 16 +- .../Routing/UrlProviderExtensions.cs | 22 +-- src/Umbraco.Core/Runtime/MainDom.cs | 10 +- .../Runtime/MainDomSemaphoreLock.cs | 2 +- .../Security/AuthenticationExtensions.cs | 6 +- .../BackOfficeExternalLoginProviderErrors.cs | 4 +- .../Security/ClaimsPrincipalExtensions.cs | 14 +- .../Security/ContentPermissions.cs | 10 +- src/Umbraco.Core/Security/ExternalLogin.cs | 4 +- src/Umbraco.Core/Security/IExternalLogin.cs | 2 +- .../Security/IIdentityUserLogin.cs | 2 +- .../Security/IdentityUserLogin.cs | 2 +- src/Umbraco.Core/Security/MediaPermissions.cs | 2 +- .../Security/UpdateMemberProfileResult.cs | 2 +- src/Umbraco.Core/Semver/Semver.cs | 14 +- .../Services/ContentServiceExtensions.cs | 4 +- .../Services/ContentTypeServiceExtensions.cs | 8 +- src/Umbraco.Core/Services/DashboardService.cs | 6 +- src/Umbraco.Core/Services/IAuditService.cs | 10 +- src/Umbraco.Core/Services/IConsentService.cs | 4 +- src/Umbraco.Core/Services/IContentService.cs | 20 +-- src/Umbraco.Core/Services/IDataTypeService.cs | 2 +- src/Umbraco.Core/Services/IEntityService.cs | 8 +- src/Umbraco.Core/Services/IFileService.cs | 6 +- .../Services/ILocalizationService.cs | 2 +- src/Umbraco.Core/Services/IMediaService.cs | 18 +- src/Umbraco.Core/Services/IMemberService.cs | 4 +- .../Services/IRedirectUrlService.cs | 2 +- src/Umbraco.Core/Services/IRelationService.cs | 2 +- src/Umbraco.Core/Services/IRuntimeState.cs | 2 +- src/Umbraco.Core/Services/ISectionService.cs | 2 +- src/Umbraco.Core/Services/ITagService.cs | 22 +-- src/Umbraco.Core/Services/ITreeService.cs | 2 +- src/Umbraco.Core/Services/IUserService.cs | 18 +- .../Services/MediaServiceExtensions.cs | 4 +- src/Umbraco.Core/Services/OperationResult.cs | 28 +-- src/Umbraco.Core/Services/Ordering.cs | 10 +- src/Umbraco.Core/Services/PublishResult.cs | 4 +- src/Umbraco.Core/Services/SectionService.cs | 2 +- src/Umbraco.Core/Services/ServiceContext.cs | 166 +++++++++--------- src/Umbraco.Core/Services/TreeService.cs | 2 +- .../Services/UserServiceExtensions.cs | 2 +- src/Umbraco.Core/Settable.cs | 19 +- src/Umbraco.Core/SimpleMainDom.cs | 2 +- .../Strings/Css/StylesheetHelper.cs | 12 +- src/Umbraco.Core/Sync/RefreshInstruction.cs | 6 +- src/Umbraco.Core/SystemLock.cs | 28 +-- .../Telemetry/ITelemetryService.cs | 2 +- .../Telemetry/Models/PackageTelemetry.cs | 2 +- .../Telemetry/TelemetryService.cs | 2 +- .../Templates/HtmlImageSourceParser.cs | 6 +- .../Templates/HtmlLocalLinkParser.cs | 20 +-- src/Umbraco.Core/Templates/HtmlUrlParser.cs | 2 +- .../Templates/UmbracoComponentRenderer.cs | 2 +- src/Umbraco.Core/Tour/BackOfficeTourFilter.cs | 8 +- src/Umbraco.Core/Trees/ISearchableTree.cs | 2 +- src/Umbraco.Core/Trees/MenuItemCollection.cs | 2 +- src/Umbraco.Core/Trees/MenuItemList.cs | 4 +- src/Umbraco.Core/Trees/Tree.cs | 2 +- src/Umbraco.Core/Trees/TreeNode.cs | 6 +- src/Umbraco.Core/Udi.cs | 8 +- src/Umbraco.Core/UdiRange.cs | 2 +- src/Umbraco.Core/UdiTypeConverter.cs | 6 +- .../Web/HybridUmbracoContextAccessor.cs | 2 +- .../Web/IUmbracoContextAccessor.cs | 2 +- src/Umbraco.Core/WebAssets/AssetFile.cs | 2 +- src/Umbraco.Core/WebAssets/BundlingOptions.cs | 2 +- src/Umbraco.Core/WebAssets/IAssetFile.cs | 2 +- src/Umbraco.Core/Xml/DynamicContext.cs | 21 +-- .../Xml/XPath/NavigableNavigator.cs | 62 ++++--- src/Umbraco.Core/Xml/XmlHelper.cs | 21 ++- .../Services/Implement/DataTypeService.cs | 8 +- 259 files changed, 1219 insertions(+), 1112 deletions(-) diff --git a/src/Umbraco.Core/AttemptOfTResult.cs b/src/Umbraco.Core/AttemptOfTResult.cs index ebe7d57d7f..20ae500a7e 100644 --- a/src/Umbraco.Core/AttemptOfTResult.cs +++ b/src/Umbraco.Core/AttemptOfTResult.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core public struct Attempt { // private - use Succeed() or Fail() methods to create attempts - private Attempt(bool? success, TResult? result, Exception? exception) + private Attempt(bool success, TResult? result, Exception? exception) { Success = success; Result = result; @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core /// /// Gets a value indicating whether this was successful. /// - public bool? Success { get; } + public bool Success { get; } /// /// Gets the exception associated with an unsuccessful attempt. @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core /// /// Gets the attempt result, if successful, else a default value. /// - public TResult? ResultOr(TResult? value) => Success.HasValue && Success.Value ? Result : value; + public TResult? ResultOr(TResult? value) => Success ? Result : value; // optimize, use a singleton failed attempt private static readonly Attempt Failed = new Attempt(false, default(TResult), null); diff --git a/src/Umbraco.Core/AttemptOfTResultTStatus.cs b/src/Umbraco.Core/AttemptOfTResultTStatus.cs index 1278da86a5..65a3e48334 100644 --- a/src/Umbraco.Core/AttemptOfTResultTStatus.cs +++ b/src/Umbraco.Core/AttemptOfTResultTStatus.cs @@ -18,7 +18,7 @@ namespace Umbraco.Cms.Core /// /// Gets the exception associated with an unsuccessful attempt. /// - public Exception Exception { get; } + public Exception? Exception { get; } /// /// Gets the attempt result. @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core public TStatus Status { get; } // private - use Succeed() or Fail() methods to create attempts - private Attempt(bool success, TResult result, TStatus status, Exception exception) + private Attempt(bool success, TResult result, TStatus status, Exception? exception) { Success = success; Result = result; @@ -44,9 +44,9 @@ namespace Umbraco.Cms.Core /// /// The status of the attempt. /// The successful attempt. - public static Attempt Succeed(TStatus status) + public static Attempt Succeed(TStatus status) { - return new Attempt(true, default(TResult), status, null); + return new Attempt(true, default(TResult), status, null); } /// @@ -65,9 +65,9 @@ namespace Umbraco.Cms.Core /// /// The status of the attempt. /// The failed attempt. - public static Attempt Fail(TStatus status) + public static Attempt Fail(TStatus status) { - return new Attempt(false, default(TResult), status, null); + return new Attempt(false, default(TResult), status, null); } /// @@ -76,9 +76,9 @@ namespace Umbraco.Cms.Core /// The status of the attempt. /// The exception causing the failure of the attempt. /// The failed attempt. - public static Attempt Fail(TStatus status, Exception exception) + public static Attempt Fail(TStatus status, Exception exception) { - return new Attempt(false, default(TResult), status, exception); + return new Attempt(false, default(TResult), status, exception); } /// @@ -111,9 +111,9 @@ namespace Umbraco.Cms.Core /// The status of the successful attempt. /// The status of the failed attempt. /// The attempt. - public static Attempt If(bool condition, TStatus succStatus, TStatus failStatus) + public static Attempt If(bool condition, TStatus succStatus, TStatus failStatus) { - return new Attempt(condition, default(TResult), condition ? succStatus : failStatus, null); + return new Attempt(condition, default(TResult), condition ? succStatus : failStatus, null); } /// diff --git a/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs index c512be301f..44d730be83 100644 --- a/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs @@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.Cache { _idKeyMap.ClearCache(payload.Id); - if (dataTypeCache.Success.HasValue && dataTypeCache.Success.Value) + if (dataTypeCache.Success) { dataTypeCache.Result?.Clear(RepositoryCacheKeys.GetKey(payload.Id)); } diff --git a/src/Umbraco.Core/Cache/MacroCacheRefresher.cs b/src/Umbraco.Core/Cache/MacroCacheRefresher.cs index 65a911c864..87db6c8538 100644 --- a/src/Umbraco.Core/Cache/MacroCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MacroCacheRefresher.cs @@ -52,7 +52,7 @@ namespace Umbraco.Cms.Core.Cache AppCaches.RuntimeCache.ClearByKey(alias); var macroRepoCache = AppCaches.IsolatedCaches.Get(); - if (macroRepoCache.Success.HasValue && macroRepoCache.Success.Value) + if (macroRepoCache.Success) { macroRepoCache.Result?.Clear(RepositoryCacheKeys.GetKey(payload.Id)); } diff --git a/src/Umbraco.Core/Cache/MediaCacheRefresher.cs b/src/Umbraco.Core/Cache/MediaCacheRefresher.cs index dd4b05aa12..2efd23d71f 100644 --- a/src/Umbraco.Core/Cache/MediaCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MediaCacheRefresher.cs @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Core.Cache if (payload.ChangeTypes == TreeChangeTypes.Remove) _idKeyMap.ClearCache(payload.Id); - if (!mediaCache.Success.HasValue || !mediaCache.Success.Value) continue; + if (!mediaCache.Success) continue; // repository cache // it *was* done for each pathId but really that does not make sense diff --git a/src/Umbraco.Core/Cache/MemberCacheRefresher.cs b/src/Umbraco.Core/Cache/MemberCacheRefresher.cs index cdee79101a..9869f226b9 100644 --- a/src/Umbraco.Core/Cache/MemberCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MemberCacheRefresher.cs @@ -74,7 +74,7 @@ namespace Umbraco.Cms.Core.Cache foreach (var p in payloads) { _idKeyMap.ClearCache(p.Id); - if (memberCache.Success.HasValue && memberCache.Success.Value) + if (memberCache.Success) { memberCache.Result?.Clear(RepositoryCacheKeys.GetKey(p.Id)); memberCache.Result?.Clear(RepositoryCacheKeys.GetKey(p.Username)); diff --git a/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs b/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs index e6ab6fa845..9f1c45374e 100644 --- a/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/RelationTypeCacheRefresher.cs @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.Cache public override void Refresh(int id) { var cache = AppCaches.IsolatedCaches.Get(); - if (cache.Success.HasValue && cache.Success.Value) cache.Result?.Clear(RepositoryCacheKeys.GetKey(id)); + if (cache.Success) cache.Result?.Clear(RepositoryCacheKeys.GetKey(id)); base.Refresh(id); } @@ -46,7 +46,7 @@ namespace Umbraco.Cms.Core.Cache public override void Remove(int id) { var cache = AppCaches.IsolatedCaches.Get(); - if (cache.Success.HasValue && cache.Success.Value) cache.Result?.Clear(RepositoryCacheKeys.GetKey(id)); + if (cache.Success) cache.Result?.Clear(RepositoryCacheKeys.GetKey(id)); base.Remove(id); } diff --git a/src/Umbraco.Core/Cache/UserCacheRefresher.cs b/src/Umbraco.Core/Cache/UserCacheRefresher.cs index 2167910a6b..10c4865ba8 100644 --- a/src/Umbraco.Core/Cache/UserCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/UserCacheRefresher.cs @@ -39,7 +39,7 @@ namespace Umbraco.Cms.Core.Cache public override void Remove(int id) { var userCache = AppCaches.IsolatedCaches.Get(); - if (userCache.Success.HasValue && userCache.Success.Value) + if (userCache.Success) { userCache.Result?.Clear(RepositoryCacheKeys.GetKey(id)); userCache.Result?.ClearByKey(CacheKeys.UserContentStartNodePathsPrefix + id); diff --git a/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs b/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs index 9ecd569e14..a889146794 100644 --- a/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/UserGroupCacheRefresher.cs @@ -34,7 +34,7 @@ namespace Umbraco.Cms.Core.Cache { ClearAllIsolatedCacheByEntityType(); var userGroupCache = AppCaches.IsolatedCaches.Get(); - if (userGroupCache.Success.HasValue && userGroupCache.Success.Value) + if (userGroupCache.Success) { userGroupCache.Result?.ClearByKey(CacheKeys.UserGroupGetByAliasCacheKeyPrefix); } @@ -54,7 +54,7 @@ namespace Umbraco.Cms.Core.Cache public override void Remove(int id) { var userGroupCache = AppCaches.IsolatedCaches.Get(); - if (userGroupCache.Success.HasValue && userGroupCache.Success.Value) + if (userGroupCache.Success) { userGroupCache.Result?.Clear(RepositoryCacheKeys.GetKey(id)); userGroupCache.Result?.ClearByKey(CacheKeys.UserGroupGetByAliasCacheKeyPrefix); diff --git a/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs b/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs index 4bd75042ca..bfd3f17cbf 100644 --- a/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs @@ -4,12 +4,12 @@ namespace Umbraco.Cms.Core.Configuration.Grid { public interface IGridEditorConfig { - string Name { get; } - string NameTemplate { get; } + string? Name { get; } + string? NameTemplate { get; } string Alias { get; } - string View { get; } - string Render { get; } - string Icon { get; } + string? View { get; } + string? Render { get; } + string? Icon { get; } IDictionary Config { get; } } } diff --git a/src/Umbraco.Core/Configuration/IUmbracoVersion.cs b/src/Umbraco.Core/Configuration/IUmbracoVersion.cs index e59fc2117d..2468c921fa 100644 --- a/src/Umbraco.Core/Configuration/IUmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/IUmbracoVersion.cs @@ -40,7 +40,7 @@ namespace Umbraco.Cms.Core.Configuration /// The semantic version is the value of the . /// It is the full version of Umbraco, including comments. /// - SemVersion? SemanticVersion { get; } + SemVersion SemanticVersion { get; } } } diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 010fc3fb58..efa1b7e120 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -63,6 +63,6 @@ namespace Umbraco.Cms.Core.Configuration /// The semantic version is the value of the . /// It is the full version of Umbraco, including comments. /// - public SemVersion? SemanticVersion { get; } + public SemVersion SemanticVersion { get; } } } diff --git a/src/Umbraco.Core/CustomBooleanTypeConverter.cs b/src/Umbraco.Core/CustomBooleanTypeConverter.cs index 6246b04bd1..253f070b40 100644 --- a/src/Umbraco.Core/CustomBooleanTypeConverter.cs +++ b/src/Umbraco.Core/CustomBooleanTypeConverter.cs @@ -8,7 +8,7 @@ namespace Umbraco.Cms.Core /// public class CustomBooleanTypeConverter : BooleanConverter { - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { if (sourceType == typeof(string)) { @@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core return base.CanConvertFrom(context, sourceType); } - public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + public override object? ConvertFrom(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { if (value is string) { diff --git a/src/Umbraco.Core/DefaultEventMessagesFactory.cs b/src/Umbraco.Core/DefaultEventMessagesFactory.cs index b795045f32..544299b03a 100644 --- a/src/Umbraco.Core/DefaultEventMessagesFactory.cs +++ b/src/Umbraco.Core/DefaultEventMessagesFactory.cs @@ -21,7 +21,7 @@ namespace Umbraco.Cms.Core return eventMessages; } - public EventMessages GetOrDefault() + public EventMessages? GetOrDefault() { return _eventMessagesAccessor.EventMessages; } diff --git a/src/Umbraco.Core/DelegateEqualityComparer.cs b/src/Umbraco.Core/DelegateEqualityComparer.cs index 6aabbf62f4..64d715c838 100644 --- a/src/Umbraco.Core/DelegateEqualityComparer.cs +++ b/src/Umbraco.Core/DelegateEqualityComparer.cs @@ -9,18 +9,18 @@ namespace Umbraco.Cms.Core /// public class DelegateEqualityComparer : IEqualityComparer { - private readonly Func _equals; + private readonly Func _equals; private readonly Func _getHashcode; #region Implementation of IEqualityComparer - public DelegateEqualityComparer(Func equals, Func getHashcode) + public DelegateEqualityComparer(Func equals, Func getHashcode) { _getHashcode = getHashcode; _equals = equals; } - public static DelegateEqualityComparer CompareMember(Func memberExpression) where TMember : IEquatable + public static DelegateEqualityComparer CompareMember(Func memberExpression) where TMember : IEquatable { return new DelegateEqualityComparer( (x, y) => memberExpression.Invoke(x).Equals((TMember)memberExpression.Invoke(y)), @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core /// true if the specified objects are equal; otherwise, false. /// /// The first object of type to compare.The second object of type to compare. - public bool Equals(T x, T y) + public bool Equals(T? x, T? y) { return _equals.Invoke(x, y); } diff --git a/src/Umbraco.Core/Events/EventAggregator.Notifications.cs b/src/Umbraco.Core/Events/EventAggregator.Notifications.cs index 85483c99d5..e195e7cfe1 100644 --- a/src/Umbraco.Core/Events/EventAggregator.Notifications.cs +++ b/src/Umbraco.Core/Events/EventAggregator.Notifications.cs @@ -16,20 +16,27 @@ namespace Umbraco.Cms.Core.Events /// public partial class EventAggregator : IEventAggregator { - private static readonly ConcurrentDictionary s_notificationAsyncHandlers - = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary s_notificationAsyncHandlers + = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary s_notificationHandlers - = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary s_notificationHandlers + = new ConcurrentDictionary(); - private Task? PublishNotificationAsync(INotification notification, CancellationToken cancellationToken = default) + private Task PublishNotificationAsync(INotification notification, CancellationToken cancellationToken = default) { Type notificationType = notification.GetType(); - NotificationAsyncHandlerWrapper? asyncHandler = s_notificationAsyncHandlers.GetOrAdd( + NotificationAsyncHandlerWrapper asyncHandler = s_notificationAsyncHandlers.GetOrAdd( notificationType, - t => (NotificationAsyncHandlerWrapper?)Activator.CreateInstance(typeof(NotificationAsyncHandlerWrapperImpl<>).MakeGenericType(notificationType))); + t => + { + var value = Activator.CreateInstance( + typeof(NotificationAsyncHandlerWrapperImpl<>).MakeGenericType(notificationType)); + return value is not null + ? (NotificationAsyncHandlerWrapper)value + : throw new InvalidCastException("Activator could not create instance of NotificationHandler"); + }); - return asyncHandler?.HandleAsync(notification, cancellationToken, _serviceFactory, PublishCoreAsync); + return asyncHandler.HandleAsync(notification, cancellationToken, _serviceFactory, PublishCoreAsync); } private void PublishNotification(INotification notification) @@ -37,7 +44,12 @@ namespace Umbraco.Cms.Core.Events Type notificationType = notification.GetType(); NotificationHandlerWrapper? asyncHandler = s_notificationHandlers.GetOrAdd( notificationType, - t => (NotificationHandlerWrapper?)Activator.CreateInstance(typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType))); + t => + { + var value = Activator.CreateInstance( + typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType)); + return value is not null ? (NotificationHandlerWrapper)value : throw new InvalidCastException("Activator could not create instance of NotificationHandler"); + }); asyncHandler?.Handle(notification, _serviceFactory, PublishCore); } diff --git a/src/Umbraco.Core/Events/EventAggregator.cs b/src/Umbraco.Core/Events/EventAggregator.cs index d5e81af9c1..5bf54b516a 100644 --- a/src/Umbraco.Core/Events/EventAggregator.cs +++ b/src/Umbraco.Core/Events/EventAggregator.cs @@ -30,7 +30,7 @@ namespace Umbraco.Cms.Core.Events => _serviceFactory = serviceFactory; /// - public Task? PublishAsync(TNotification notification, CancellationToken cancellationToken = default) + public Task PublishAsync(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification { // TODO: Introduce codegen efficient Guard classes to reduce noise. diff --git a/src/Umbraco.Core/Events/IEventAggregator.cs b/src/Umbraco.Core/Events/IEventAggregator.cs index 77197b121f..c654bb6c86 100644 --- a/src/Umbraco.Core/Events/IEventAggregator.cs +++ b/src/Umbraco.Core/Events/IEventAggregator.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core.Events /// The notification object. /// An optional cancellation token. /// A task that represents the publish operation. - Task? PublishAsync(TNotification notification, CancellationToken cancellationToken = default) + Task PublishAsync(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification; /// diff --git a/src/Umbraco.Core/Events/IEventMessagesAccessor.cs b/src/Umbraco.Core/Events/IEventMessagesAccessor.cs index 7d95ae1cb5..cffff705da 100644 --- a/src/Umbraco.Core/Events/IEventMessagesAccessor.cs +++ b/src/Umbraco.Core/Events/IEventMessagesAccessor.cs @@ -2,6 +2,6 @@ { public interface IEventMessagesAccessor { - EventMessages EventMessages { get; set; } + EventMessages? EventMessages { get; set; } } } diff --git a/src/Umbraco.Core/ExpressionHelper.cs b/src/Umbraco.Core/ExpressionHelper.cs index bb59605a46..1895364d17 100644 --- a/src/Umbraco.Core/ExpressionHelper.cs +++ b/src/Umbraco.Core/ExpressionHelper.cs @@ -66,14 +66,14 @@ namespace Umbraco.Cms.Core } - var propInfo = member.Member as PropertyInfo; + var propInfo = member!.Member as PropertyInfo; if (propInfo == null) throw new ArgumentException(string.Format( "Expression '{0}' refers to a field, not a property.", propertyLambda)); if (type != propInfo.ReflectedType && - !type.IsSubclassOf(propInfo.ReflectedType)) + !type.IsSubclassOf(propInfo.ReflectedType!)) throw new ArgumentException(string.Format( "Expression '{0}' refers to a property that is not from type {1}.", propertyLambda, @@ -83,7 +83,7 @@ namespace Umbraco.Cms.Core }); } - public static (MemberInfo, string) FindProperty(LambdaExpression lambda) + public static (MemberInfo, string?) FindProperty(LambdaExpression lambda) { void Throw() { @@ -92,7 +92,7 @@ namespace Umbraco.Cms.Core Expression expr = lambda; var loop = true; - string alias = null; + string? alias = null; while (loop) { switch (expr.NodeType) @@ -109,11 +109,11 @@ namespace Umbraco.Cms.Core if (method.DeclaringType != typeof(SqlExtensionsStatics) || method.Name != "Alias" || !(callExpr.Arguments[1] is ConstantExpression aliasExpr)) Throw(); expr = callExpr.Arguments[0]; - alias = aliasExpr.Value.ToString(); + alias = aliasExpr.Value?.ToString(); break; case ExpressionType.MemberAccess: var memberExpr = (MemberExpression) expr; - if (memberExpr.Expression.NodeType != ExpressionType.Parameter && memberExpr.Expression.NodeType != ExpressionType.Convert) + if (memberExpr.Expression?.NodeType != ExpressionType.Parameter && memberExpr.Expression?.NodeType != ExpressionType.Convert) Throw(); return (memberExpr.Member, alias); default: @@ -125,22 +125,22 @@ namespace Umbraco.Cms.Core throw new Exception("Configuration for members is only supported for top-level individual members on a type."); } - public static IDictionary GetMethodParams(Expression> fromExpression) + public static IDictionary? GetMethodParams(Expression> fromExpression) { if (fromExpression == null) return null; var body = fromExpression.Body as MethodCallExpression; if (body == null) - return new Dictionary(); + return new Dictionary(); - var rVal = new Dictionary(); - var parameters = body.Method.GetParameters().Select(x => x.Name).ToArray(); + var rVal = new Dictionary(); + var parameters = body.Method.GetParameters().Select(x => x.Name).Where(x => x is not null).ToArray(); var i = 0; foreach (var argument in body.Arguments) { var lambda = Expression.Lambda(argument, fromExpression.Parameters); var d = lambda.Compile(); var value = d.DynamicInvoke(new object[1]); - rVal.Add(parameters[i], value); + rVal.Add(parameters[i]!, value); i++; } return rVal; @@ -153,7 +153,7 @@ namespace Umbraco.Cms.Core /// From expression. /// The or null if is null or cannot be converted to . /// - public static MethodInfo GetMethodInfo(Expression> fromExpression) + public static MethodInfo? GetMethodInfo(Expression> fromExpression) { if (fromExpression == null) return null; var body = fromExpression.Body as MethodCallExpression; @@ -166,7 +166,7 @@ namespace Umbraco.Cms.Core /// The return type of the method. /// From expression. /// - public static MethodInfo GetMethodInfo(Expression> fromExpression) + public static MethodInfo? GetMethodInfo(Expression> fromExpression) { if (fromExpression == null) return null; var body = fromExpression.Body as MethodCallExpression; @@ -180,11 +180,11 @@ namespace Umbraco.Cms.Core /// The type of the 2. /// From expression. /// - public static MethodInfo GetMethodInfo(Expression> fromExpression) + public static MethodInfo? GetMethodInfo(Expression> fromExpression) { if (fromExpression == null) return null; - MethodCallExpression me; + MethodCallExpression? me; switch (fromExpression.Body.NodeType) { case ExpressionType.Convert: @@ -206,7 +206,7 @@ namespace Umbraco.Cms.Core /// The expression. /// The or null if cannot be converted to . /// - public static MethodInfo GetMethod(Expression expression) + public static MethodInfo? GetMethod(Expression expression) { if (expression == null) return null; return IsMethod(expression) ? (((MethodCallExpression)expression).Method) : null; @@ -220,11 +220,11 @@ namespace Umbraco.Cms.Core /// From expression. /// The or null if cannot be converted to . /// - public static MemberInfo GetMemberInfo(Expression> fromExpression) + public static MemberInfo? GetMemberInfo(Expression> fromExpression) { if (fromExpression == null) return null; - MemberExpression me; + MemberExpression? me; switch (fromExpression.Body.NodeType) { case ExpressionType.Convert: @@ -283,7 +283,7 @@ namespace Umbraco.Cms.Core /// The expression. /// /// - public static MemberInfo GetMember(Expression expression) + public static MemberInfo? GetMember(Expression expression) { if (expression == null) return null; return IsMember(expression) ? (((MemberExpression)expression).Member) : null; @@ -361,7 +361,7 @@ namespace Umbraco.Cms.Core /// The arguments. /// /// - public static object GetFirstValueFromArguments(IEnumerable arguments) + public static object? GetFirstValueFromArguments(IEnumerable arguments) { if (arguments == null) return false; return diff --git a/src/Umbraco.Core/Extensions/ContentExtensions.cs b/src/Umbraco.Core/Extensions/ContentExtensions.cs index 904ca9941a..63bebcca46 100644 --- a/src/Umbraco.Core/Extensions/ContentExtensions.cs +++ b/src/Umbraco.Core/Extensions/ContentExtensions.cs @@ -37,15 +37,15 @@ namespace Umbraco.Extensions string? culture = null, string? segment = null) { - if (!content.Properties.TryGetValue(propertyTypeAlias, out IProperty property)) + if (!content.Properties.TryGetValue(propertyTypeAlias, out IProperty? property)) { mediaFilePath = null; return false; } if (!mediaUrlGenerators.TryGetMediaPath( - property.PropertyType.PropertyEditorAlias, - property.GetValue(culture, segment), + property?.PropertyType?.PropertyEditorAlias, + property?.GetValue(culture, segment), out mediaFilePath)) { return false; @@ -112,15 +112,15 @@ namespace Umbraco.Extensions /// /// This is a bit of a hack because we need to type check! /// - internal static bool HasChildren(IContentBase content, ServiceContext services) + internal static bool? HasChildren(IContentBase content, ServiceContext services) { if (content is IContent) { - return services.ContentService.HasChildren(content.Id); + return services.ContentService?.HasChildren(content.Id); } if (content is IMedia) { - return services.MediaService.HasChildren(content.Id); + return services.MediaService?.HasChildren(content.Id); } return false; } @@ -133,7 +133,7 @@ namespace Umbraco.Extensions /// /// public static IEnumerable GetPropertiesByEditor(this IContentBase content, string editorAlias) - => content.Properties.Where(x => x.PropertyType.PropertyEditorAlias == editorAlias); + => content.Properties.Where(x => x.PropertyType?.PropertyEditorAlias == editorAlias); #region IContent @@ -224,8 +224,8 @@ namespace Umbraco.Extensions public static IEnumerable GetNonGroupedProperties(this IContentBase content) { return content.Properties - .Where(x => x.PropertyType.PropertyGroupId == null) - .OrderBy(x => x.PropertyType.SortOrder); + .Where(x => x.PropertyType?.PropertyGroupId == null) + .OrderBy(x => x.PropertyType?.SortOrder); } /// diff --git a/src/Umbraco.Core/Extensions/DelegateExtensions.cs b/src/Umbraco.Core/Extensions/DelegateExtensions.cs index 40ee011641..4cbcdd5d6a 100644 --- a/src/Umbraco.Core/Extensions/DelegateExtensions.cs +++ b/src/Umbraco.Core/Extensions/DelegateExtensions.cs @@ -20,7 +20,7 @@ namespace Umbraco.Extensions do { var result = task(); - if (result.Success.HasValue && result.Success.Value) { return result; } + if (result.Success) { return result; } Thread.Sleep((int)pause.TotalMilliseconds); } while (stopwatch.Elapsed < timeout); @@ -38,7 +38,7 @@ namespace Umbraco.Extensions { attempts++; var result = task(attempts); - if (result.Success.HasValue && result.Success.Value) { return result; } + if (result.Success) { return result; } Thread.Sleep((int)pause.TotalMilliseconds); } while (attempts < totalAttempts); diff --git a/src/Umbraco.Core/Extensions/EnumerableExtensions.cs b/src/Umbraco.Core/Extensions/EnumerableExtensions.cs index 7abfcf0546..44e17081e5 100644 --- a/src/Umbraco.Core/Extensions/EnumerableExtensions.cs +++ b/src/Umbraco.Core/Extensions/EnumerableExtensions.cs @@ -81,7 +81,7 @@ namespace Umbraco.Extensions /// Source type /// Key type /// the unique list - public static IEnumerable LegacyDistinctBy(this IEnumerable source, Func keySelector) + public static IEnumerable LegacyDistinctBy(this IEnumerable source, Func keySelector) where TKey : IEquatable { return source.Distinct(DelegateEqualityComparer.CompareMember(keySelector)); @@ -303,7 +303,7 @@ namespace Umbraco.Extensions /// /// There's a few answers, this one seems the best for it's simplicity and based on the comment of Eamon /// - public static bool UnsortedSequenceEqual(this IEnumerable source, IEnumerable other) + public static bool UnsortedSequenceEqual(this IEnumerable? source, IEnumerable? other) { if (source == null && other == null) return true; if (source == null || other == null) return false; diff --git a/src/Umbraco.Core/Extensions/NameValueCollectionExtensions.cs b/src/Umbraco.Core/Extensions/NameValueCollectionExtensions.cs index 9ebc218929..a07abfbd96 100644 --- a/src/Umbraco.Core/Extensions/NameValueCollectionExtensions.cs +++ b/src/Umbraco.Core/Extensions/NameValueCollectionExtensions.cs @@ -37,7 +37,7 @@ namespace Umbraco.Extensions var result = val.TryConvertTo(); - return result.Success.HasValue && result.Success.Value ? result.Result : defaultIfNotFound; + return result.Success ? result.Result : defaultIfNotFound; } } } diff --git a/src/Umbraco.Core/Extensions/ObjectExtensions.cs b/src/Umbraco.Core/Extensions/ObjectExtensions.cs index 2013c35e24..ec2257e637 100644 --- a/src/Umbraco.Core/Extensions/ObjectExtensions.cs +++ b/src/Umbraco.Core/Extensions/ObjectExtensions.cs @@ -79,7 +79,7 @@ namespace Umbraco.Extensions { Attempt result = TryConvertTo(input, typeof(T)); - if (result.Success.HasValue && result.Success.Value) + if (result.Success) { return Attempt.Succeed((T?)result.Result); } @@ -173,7 +173,7 @@ namespace Umbraco.Extensions var inner = input.TryConvertTo(underlying); // And if successful, fall on through to rewrap in a nullable; if failed, pass on the exception - if (inner.Success.HasValue && inner.Success.Value) + if (inner.Success) { input = inner.Result; // Now fall on through... } @@ -608,10 +608,10 @@ namespace Umbraco.Extensions /// /// The Type can only be a primitive type or Guid and byte[] otherwise an exception is thrown /// - public static string? ToXmlString(this object value, Type type) + public static string ToXmlString(this object value, Type type) { if (value == null) return string.Empty; - if (type == typeof(string)) return (value.ToString().IsNullOrWhiteSpace() ? "" : value.ToString()); + if (type == typeof(string)) return (value.ToString().IsNullOrWhiteSpace() ? "" : value.ToString()!); if (type == typeof(bool)) return XmlConvert.ToString((bool)value); if (type == typeof(byte)) return XmlConvert.ToString((byte)value); if (type == typeof(char)) return XmlConvert.ToString((char)value); @@ -640,7 +640,7 @@ namespace Umbraco.Extensions /// /// /// - public static string? ToXmlString(this object value) + public static string ToXmlString(this object value) { return value.ToXmlString(typeof (T)); } diff --git a/src/Umbraco.Core/Extensions/PublishedPropertyExtension.cs b/src/Umbraco.Core/Extensions/PublishedPropertyExtension.cs index dcfd6900ef..3ff5c77719 100644 --- a/src/Umbraco.Core/Extensions/PublishedPropertyExtension.cs +++ b/src/Umbraco.Core/Extensions/PublishedPropertyExtension.cs @@ -38,7 +38,7 @@ namespace Umbraco.Extensions } var valueConverted = value.TryConvertTo(); - if (valueConverted.Success.HasValue && valueConverted.Success.Value) + if (valueConverted.Success) { return valueConverted.Result; } @@ -63,7 +63,7 @@ namespace Umbraco.Extensions } var noValueConverted = noValue.TryConvertTo(); - if (noValueConverted.Success.HasValue && noValueConverted.Success.Value) + if (noValueConverted.Success) { return noValueConverted.Result; } diff --git a/src/Umbraco.Core/Extensions/PublishedSnapshotAccessorExtensions.cs b/src/Umbraco.Core/Extensions/PublishedSnapshotAccessorExtensions.cs index 727a7b5c6b..bffa642ffe 100644 --- a/src/Umbraco.Core/Extensions/PublishedSnapshotAccessorExtensions.cs +++ b/src/Umbraco.Core/Extensions/PublishedSnapshotAccessorExtensions.cs @@ -5,7 +5,7 @@ namespace Umbraco.Extensions { public static class PublishedSnapshotAccessorExtensions { - public static IPublishedSnapshot GetRequiredPublishedSnapshot(this IPublishedSnapshotAccessor publishedSnapshotAccessor) + public static IPublishedSnapshot? GetRequiredPublishedSnapshot(this IPublishedSnapshotAccessor publishedSnapshotAccessor) { if (publishedSnapshotAccessor.TryGetPublishedSnapshot(out var publishedSnapshot)) { diff --git a/src/Umbraco.Core/Extensions/StringExtensions.cs b/src/Umbraco.Core/Extensions/StringExtensions.cs index 7661fc44d3..cd629288e6 100644 --- a/src/Umbraco.Core/Extensions/StringExtensions.cs +++ b/src/Umbraco.Core/Extensions/StringExtensions.cs @@ -43,7 +43,7 @@ namespace Umbraco.Extensions { var nodeIds = path.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries) .Select(x => int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out var output) ? Attempt.Succeed(output) : Attempt.Fail()) - .Where(x => x.Success ?? false) + .Where(x => x.Success) .Select(x=>x.Result) .Reverse() .ToArray(); @@ -365,7 +365,7 @@ namespace Umbraco.Extensions /// returns . public static bool IsNullOrWhiteSpace(this string? value) => string.IsNullOrWhiteSpace(value); - public static string IfNullOrWhiteSpace(this string str, string defaultValue) + public static string? IfNullOrWhiteSpace(this string str, string? defaultValue) { return str.IsNullOrWhiteSpace() ? defaultValue : str; } diff --git a/src/Umbraco.Core/Extensions/UmbracoContextAccessorExtensions.cs b/src/Umbraco.Core/Extensions/UmbracoContextAccessorExtensions.cs index c1b9e7efa5..794c206db8 100644 --- a/src/Umbraco.Core/Extensions/UmbracoContextAccessorExtensions.cs +++ b/src/Umbraco.Core/Extensions/UmbracoContextAccessorExtensions.cs @@ -15,7 +15,7 @@ namespace Umbraco.Extensions { throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); } - return umbracoContext; + return umbracoContext!; } } } diff --git a/src/Umbraco.Core/Extensions/XmlExtensions.cs b/src/Umbraco.Core/Extensions/XmlExtensions.cs index 423039a86a..141f4a0c19 100644 --- a/src/Umbraco.Core/Extensions/XmlExtensions.cs +++ b/src/Umbraco.Core/Extensions/XmlExtensions.cs @@ -254,7 +254,7 @@ namespace Umbraco.Extensions } Attempt result = attribute.Value.TryConvertTo(); - if (result.Success.HasValue && result.Success.Value) + if (result.Success) { return result.Result; } @@ -272,7 +272,7 @@ namespace Umbraco.Extensions var val = xml.Attribute(attributeName)?.Value; var result = val.TryConvertTo(); - if (result.Success.HasValue && result.Success.Value) + if (result.Success) return result.Result; return default(T); @@ -288,7 +288,7 @@ namespace Umbraco.Extensions var val = xml.Attributes[attributeName]?.Value; var result = val.TryConvertTo(); - if (result.Success.HasValue && result.Success.Value) + if (result.Success) return result.Result; return default(T); diff --git a/src/Umbraco.Core/HybridAccessorBase.cs b/src/Umbraco.Core/HybridAccessorBase.cs index 51c89ab66d..3200f97d7d 100644 --- a/src/Umbraco.Core/HybridAccessorBase.cs +++ b/src/Umbraco.Core/HybridAccessorBase.cs @@ -21,7 +21,7 @@ namespace Umbraco.Cms.Core private readonly IRequestCache _requestCache; private string? _itemKey; - protected string ItemKey => _itemKey ??= GetType().FullName; + protected string ItemKey => _itemKey ??= GetType().FullName!; // read // http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html diff --git a/src/Umbraco.Core/HybridEventMessagesAccessor.cs b/src/Umbraco.Core/HybridEventMessagesAccessor.cs index d28561c12f..14fa0433ce 100644 --- a/src/Umbraco.Core/HybridEventMessagesAccessor.cs +++ b/src/Umbraco.Core/HybridEventMessagesAccessor.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core { } - public EventMessages EventMessages + public EventMessages? EventMessages { get { return Value; } set { Value = value; } diff --git a/src/Umbraco.Core/IO/MediaFileManager.cs b/src/Umbraco.Core/IO/MediaFileManager.cs index 73a451f118..76ce9fe1ba 100644 --- a/src/Umbraco.Core/IO/MediaFileManager.cs +++ b/src/Umbraco.Core/IO/MediaFileManager.cs @@ -162,7 +162,7 @@ namespace Umbraco.Cms.Core.IO /// If an is provided then that file (and associated thumbnails if any) is deleted /// before the new file is saved, and depending on the media path scheme, the folder may be reused for the new file. /// - public string StoreFile(IContentBase content, IPropertyType propertyType, string filename, Stream filestream, string? oldpath) + public string StoreFile(IContentBase content, IPropertyType? propertyType, string filename, Stream filestream, string? oldpath) { if (content == null) { diff --git a/src/Umbraco.Core/LambdaExpressionCacheKey.cs b/src/Umbraco.Core/LambdaExpressionCacheKey.cs index 72fd9b3c6d..123654bbe2 100644 --- a/src/Umbraco.Core/LambdaExpressionCacheKey.cs +++ b/src/Umbraco.Core/LambdaExpressionCacheKey.cs @@ -15,7 +15,7 @@ namespace Umbraco.Cms.Core { ReturnType = returnType; ExpressionAsString = expression; - ArgTypes = new HashSet(argTypes); + ArgTypes = new HashSet(argTypes); _toString = null; } @@ -23,26 +23,26 @@ namespace Umbraco.Cms.Core { ReturnType = obj.ReturnType.FullName; ExpressionAsString = obj.ToString(); - ArgTypes = new HashSet(obj.Parameters.Select(x => x.Type.FullName)); + ArgTypes = new HashSet(obj.Parameters.Select(x => x.Type.FullName)); _toString = null; } /// /// The argument type names of the /// - public readonly HashSet ArgTypes; + public readonly HashSet ArgTypes; /// /// The return type of the /// - public readonly string ReturnType; + public readonly string? ReturnType; /// /// The original string representation of the /// public readonly string ExpressionAsString; - private string _toString; + private string? _toString; /// /// Returns a that represents this instance. @@ -62,7 +62,7 @@ namespace Umbraco.Cms.Core /// /// true if the specified is equal to this instance; otherwise, false. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(obj, null)) return false; var casted = (LambdaExpressionCacheKey)obj; diff --git a/src/Umbraco.Core/Macros/IMacroRenderer.cs b/src/Umbraco.Core/Macros/IMacroRenderer.cs index 96d450c1e3..fc3319c55c 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/Media/Exif/ExifExtendedProperty.cs b/src/Umbraco.Core/Media/Exif/ExifExtendedProperty.cs index 662390c065..9aa62f4ea3 100644 --- a/src/Umbraco.Core/Media/Exif/ExifExtendedProperty.cs +++ b/src/Umbraco.Core/Media/Exif/ExifExtendedProperty.cs @@ -7,6 +7,7 @@ namespace Umbraco.Cms.Core.Media.Exif /// Represents an enumerated value. /// internal class ExifEnumProperty : ExifProperty + where T : notnull { protected T mValue; protected bool mIsBitField; @@ -16,7 +17,7 @@ namespace Umbraco.Cms.Core.Media.Exif static public implicit operator T(ExifEnumProperty obj) { return (T)obj.mValue; } - public override string ToString() { return mValue.ToString(); } + public override string? ToString() { return mValue.ToString(); } public ExifEnumProperty(ExifTag tag, T value, bool isbitfield) : base(tag) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index e854e6bf6d..bfd6024bb6 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -233,12 +233,12 @@ namespace Umbraco.Cms.Core.Models } /// - public string? GetPublishName(string culture) + public string? GetPublishName(string? culture) { if (culture.IsNullOrWhiteSpace()) return PublishName; if (!ContentType.VariesByCulture()) return null; if (_publishInfos == null) return null; - return _publishInfos.TryGetValue(culture, out var infos) ? infos.Name : null; + return _publishInfos.TryGetValue(culture!, out var infos) ? infos.Name : null; } /// diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index ee5a89c734..31c87853e7 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -310,7 +310,7 @@ namespace Umbraco.Cms.Core.Models public object? GetValue(string propertyTypeAlias, string? culture = null, string? segment = null, bool published = false) { return Properties.TryGetValue(propertyTypeAlias, out var property) - ? property.GetValue(culture, segment, published) + ? property?.GetValue(culture, segment, published) : null; } @@ -320,17 +320,17 @@ namespace Umbraco.Cms.Core.Models if (!Properties.TryGetValue(propertyTypeAlias, out var property)) return default; - var convertAttempt = property.GetValue(culture, segment, published).TryConvertTo(); - return convertAttempt.Success is not null && convertAttempt.Success.Value ? convertAttempt.Result : default; + var convertAttempt = property?.GetValue(culture, segment, published).TryConvertTo(); + return convertAttempt?.Success is not null && (convertAttempt?.Success ?? false) ? convertAttempt.Value.Result : default; } /// - public void SetValue(string propertyTypeAlias, object value, string? culture = null, string? segment = null) + public void SetValue(string propertyTypeAlias, object? value, string? culture = null, string? segment = null) { if (!Properties.TryGetValue(propertyTypeAlias, out var property)) throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); - property.SetValue(value, culture, segment); + property?.SetValue(value, culture, segment); //bump the culture to be flagged for updating this.TouchCulture(culture); @@ -435,7 +435,7 @@ namespace Umbraco.Cms.Core.Models return _currentCultureChanges.updatedCultures?.Contains(culture) ?? false; } - return Properties.Contains(propertyName) && Properties[propertyName].IsDirty(); + return Properties.Contains(propertyName) && (Properties[propertyName]?.IsDirty() ?? false); } /// @@ -462,7 +462,7 @@ namespace Umbraco.Cms.Core.Models return _previousCultureChanges.updatedCultures?.Contains(culture) ?? false; } - return Properties.Contains(propertyName) && Properties[propertyName].WasDirty(); + return Properties.Contains(propertyName) && (Properties[propertyName]?.WasDirty() ?? false); } /// diff --git a/src/Umbraco.Core/Models/ContentBaseExtensions.cs b/src/Umbraco.Core/Models/ContentBaseExtensions.cs index 973d24f13c..b81cf398bf 100644 --- a/src/Umbraco.Core/Models/ContentBaseExtensions.cs +++ b/src/Umbraco.Core/Models/ContentBaseExtensions.cs @@ -19,7 +19,7 @@ namespace Umbraco.Extensions /// /// The culture. /// The URL segment. - public static string GetUrlSegment(this IContentBase content, IShortStringHelper shortStringHelper, IEnumerable urlSegmentProviders, string? culture = null) + public static string? GetUrlSegment(this IContentBase content, IShortStringHelper shortStringHelper, IEnumerable urlSegmentProviders, string? culture = null) { if (content == null) throw new ArgumentNullException(nameof(content)); if (urlSegmentProviders == null) throw new ArgumentNullException(nameof(urlSegmentProviders)); @@ -38,6 +38,6 @@ namespace Umbraco.Extensions return url; } - private static DefaultUrlSegmentProvider s_defaultUrlSegmentProvider; + private static DefaultUrlSegmentProvider? s_defaultUrlSegmentProvider; } } diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDisplay.cs b/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDisplay.cs index a174de7a13..b31caaa901 100644 --- a/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDisplay.cs +++ b/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDisplay.cs @@ -28,13 +28,13 @@ namespace Umbraco.Cms.Core.Models.ContentEditing public string? View { get; set; } [DataMember(Name = "config")] - public IDictionary Config { get; set; } + public IDictionary? Config { get; set; } [DataMember(Name = "hideLabel")] public bool HideLabel { get; set; } [DataMember(Name = "labelOnTop")] - public bool LabelOnTop { get; set; } + public bool? LabelOnTop { get; set; } [DataMember(Name = "validation")] public PropertyTypeValidation Validation { get; set; } diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDto.cs b/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDto.cs index e12a7bbdba..d40a25805e 100644 --- a/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDto.cs +++ b/src/Umbraco.Core/Models/ContentEditing/ContentPropertyDto.cs @@ -13,7 +13,7 @@ public bool? IsRequired { get; set; } - public bool LabelOnTop { get; set; } + public bool? LabelOnTop { get; set; } public string? IsRequiredMessage { get; set; } diff --git a/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldDisplay.cs b/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldDisplay.cs index 72afedb407..97a2177167 100644 --- a/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldDisplay.cs +++ b/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldDisplay.cs @@ -13,13 +13,13 @@ namespace Umbraco.Cms.Core.Models.ContentEditing /// The name to display for this pre-value field /// [DataMember(Name = "label", IsRequired = true)] - public string Name { get; set; } + public string? Name { get; set; } /// /// The description to display for this pre-value field /// [DataMember(Name = "description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Specifies whether to hide the label for the pre-value @@ -31,12 +31,12 @@ namespace Umbraco.Cms.Core.Models.ContentEditing /// The view to render for the field /// [DataMember(Name = "view", IsRequired = true)] - public string View { get; set; } + public string? View { get; set; } /// /// This allows for custom configuration to be injected into the pre-value editor /// [DataMember(Name = "config")] - public IDictionary Config { get; set; } + public IDictionary? Config { get; set; } } } diff --git a/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldSave.cs b/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldSave.cs index 7f88a7c1f9..d75e5863f3 100644 --- a/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldSave.cs +++ b/src/Umbraco.Core/Models/ContentEditing/DataTypeConfigurationFieldSave.cs @@ -12,12 +12,12 @@ namespace Umbraco.Cms.Core.Models.ContentEditing /// Gets or sets the configuration field key. /// [DataMember(Name = "key", IsRequired = true)] - public string Key { get; set; } + public string? Key { get; set; } /// /// Gets or sets the configuration field value. /// [DataMember(Name = "value", IsRequired = true)] - public object Value { get; set; } + public object? Value { get; set; } } } diff --git a/src/Umbraco.Core/Models/ContentEditing/MacroParameter.cs b/src/Umbraco.Core/Models/ContentEditing/MacroParameter.cs index a53dc2069a..5282d09edb 100644 --- a/src/Umbraco.Core/Models/ContentEditing/MacroParameter.cs +++ b/src/Umbraco.Core/Models/ContentEditing/MacroParameter.cs @@ -25,19 +25,19 @@ namespace Umbraco.Cms.Core.Models.ContentEditing /// [DataMember(Name = "view", IsRequired = true)] [Required(AllowEmptyStrings = false)] - public string View { get; set; } + public string? View { get; set; } /// /// The configuration for this parameter editor /// [DataMember(Name = "config", IsRequired = true)] [Required(AllowEmptyStrings = false)] - public IDictionary Configuration { get; set; } + public IDictionary? Configuration { get; set; } /// /// Since we don't post this back this isn't currently really used on the server side /// [DataMember(Name = "value")] - public object Value { get; set; } + public object? Value { get; set; } } } diff --git a/src/Umbraco.Core/Models/ContentEditing/PropertyEditorBasic.cs b/src/Umbraco.Core/Models/ContentEditing/PropertyEditorBasic.cs index 7c71cb4a63..b73f2897e7 100644 --- a/src/Umbraco.Core/Models/ContentEditing/PropertyEditorBasic.cs +++ b/src/Umbraco.Core/Models/ContentEditing/PropertyEditorBasic.cs @@ -9,12 +9,12 @@ namespace Umbraco.Cms.Core.Models.ContentEditing public class PropertyEditorBasic { [DataMember(Name = "alias")] - public string Alias { get; set; } + public string? Alias { get; set; } [DataMember(Name = "name")] - public string Name { get; set; } + public string? Name { get; set; } [DataMember(Name = "icon")] - public string Icon { get; set; } + public string? Icon { get; set; } } } diff --git a/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasic.cs b/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasic.cs index 46af8be3d6..8519cace1e 100644 --- a/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasic.cs +++ b/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasic.cs @@ -41,7 +41,7 @@ namespace Umbraco.Cms.Core.Models.ContentEditing [Required] [DataMember(Name = "name")] - public string Name { get; set; } + public string? Name { get; set; } [Required] [DataMember(Name = "alias")] diff --git a/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasicExtensions.cs b/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasicExtensions.cs index c037de50d6..6f1317f3eb 100644 --- a/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasicExtensions.cs +++ b/src/Umbraco.Core/Models/ContentEditing/PropertyGroupBasicExtensions.cs @@ -2,7 +2,7 @@ { internal static class PropertyGroupBasicExtensions { - public static string GetParentAlias(this PropertyGroupBasic propertyGroup) + public static string? GetParentAlias(this PropertyGroupBasic propertyGroup) => PropertyGroupExtensions.GetParentAlias(propertyGroup.Alias); } } diff --git a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs index 8d816ab220..520fec3afe 100644 --- a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs +++ b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs @@ -26,8 +26,16 @@ namespace Umbraco.Extensions /// public static void TouchCulture(this IContentBase content, string? culture) { - if (culture.IsNullOrWhiteSpace()) return; - if (!content.CultureInfos?.TryGetValue(culture!, out var infos) ?? true) return; + if (culture.IsNullOrWhiteSpace() || content.CultureInfos is null) + { + return; + } + + if (!content.CultureInfos.TryGetValue(culture!, out var infos)) + { + return; + } + content.CultureInfos?.AddOrUpdate(culture!, infos.Name, DateTime.Now); } @@ -46,7 +54,12 @@ namespace Umbraco.Extensions { foreach(var culture in content.EditedCultures.ToList()) { - if (!content.CultureInfos?.TryGetValue(culture, out var editedInfos) ?? true) + if (content.CultureInfos is null) + { + continue; + } + + if (!content.CultureInfos.TryGetValue(culture, out var editedInfos)) { continue; } @@ -69,7 +82,11 @@ namespace Umbraco.Extensions foreach (var culture in content.PublishedCultures.ToList()) { - if (!content.PublishCultureInfos?.TryGetValue(culture, out ContentCultureInfos publishInfos) ?? true) + if (content.PublishCultureInfos is null) + { + continue; + } + if (!content.PublishCultureInfos.TryGetValue(culture, out ContentCultureInfos publishInfos)) { continue; } @@ -131,12 +148,12 @@ namespace Umbraco.Extensions foreach (var property in content.Properties) { // each property type may or may not support the variation - if (!property.PropertyType.SupportsVariation(culture, "*", wildcards: true)) + if (!property.PropertyType?.SupportsVariation(culture, "*", wildcards: true) ?? false) continue; foreach (var pvalue in property.Values) - if (property.PropertyType.SupportsVariation(pvalue.Culture, pvalue.Segment, wildcards: true) && - (culture == "*" || pvalue.Culture.InvariantEquals(culture))) + if ((property.PropertyType?.SupportsVariation(pvalue.Culture, pvalue.Segment, wildcards: true) ?? false) && + (culture == "*" || (pvalue.Culture?.InvariantEquals(culture) ?? false))) { property.SetValue(null, pvalue.Culture, pvalue.Segment); } @@ -146,14 +163,14 @@ namespace Umbraco.Extensions var otherProperties = other.Properties; foreach (var otherProperty in otherProperties) { - if (!otherProperty.PropertyType.SupportsVariation(culture, "*", wildcards: true)) + if (!otherProperty.PropertyType?.SupportsVariation(culture, "*", wildcards: true) ?? true) continue; var alias = otherProperty.PropertyType.Alias; foreach (var pvalue in otherProperty.Values) { if (otherProperty.PropertyType.SupportsVariation(pvalue.Culture, pvalue.Segment, wildcards: true) && - (culture == "*" || pvalue.Culture.InvariantEquals(culture))) + (culture == "*" || (pvalue.Culture?.InvariantEquals(culture) ?? false))) { var value = published ? pvalue.PublishedValue : pvalue.EditedValue; content.SetValue(alias, value, pvalue.Culture, pvalue.Segment); diff --git a/src/Umbraco.Core/Models/DataType.cs b/src/Umbraco.Core/Models/DataType.cs index 8678f4947b..bde06414a1 100644 --- a/src/Umbraco.Core/Models/DataType.cs +++ b/src/Umbraco.Core/Models/DataType.cs @@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.Models [DataContract(IsReference = true)] public class DataType : TreeEntityBase, IDataType { - private IDataEditor _editor; + private IDataEditor? _editor; private ValueStorageType _databaseType; private readonly IConfigurationEditorJsonSerializer _serializer; private object? _configuration; @@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.Models /// /// Initializes a new instance of the class. /// - public DataType(IDataEditor editor, IConfigurationEditorJsonSerializer serializer, int parentId = -1) + public DataType(IDataEditor? editor, IConfigurationEditorJsonSerializer serializer, int parentId = -1) { _editor = editor ?? throw new ArgumentNullException(nameof(editor)); _serializer = serializer ?? throw new ArgumentNullException(nameof(editor)); @@ -36,13 +36,13 @@ namespace Umbraco.Cms.Core.Models /// [IgnoreDataMember] - public IDataEditor Editor + public IDataEditor? Editor { get => _editor; set { // ignore if no change - if (_editor.Alias == value.Alias) return; + if (_editor?.Alias == value?.Alias) return; OnPropertyChanged(nameof(Editor)); // try to map the existing configuration to the new configuration @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Core.Models try { - Configuration = _editor.GetConfigurationEditor().FromDatabase(json, _serializer); + Configuration = _editor?.GetConfigurationEditor().FromDatabase(json, _serializer); } catch (Exception e) { @@ -65,7 +65,7 @@ namespace Umbraco.Cms.Core.Models /// [DataMember] - public string EditorAlias => _editor.Alias; + public string EditorAlias => _editor?.Alias ?? string.Empty; /// [DataMember] @@ -89,7 +89,7 @@ namespace Umbraco.Cms.Core.Models try { - _configuration = _editor.GetConfigurationEditor().FromDatabase(_configurationJson, _serializer); + _configuration = _editor?.GetConfigurationEditor().FromDatabase(_configurationJson, _serializer); } catch (Exception e) { @@ -113,8 +113,8 @@ namespace Umbraco.Cms.Core.Models throw new ArgumentException("Configurations are kinda non-mutable. Do not reassign the same object.", nameof(value)); // validate configuration type - if (!_editor.GetConfigurationEditor().IsConfiguration(value)) - throw new ArgumentException($"Value of type {value.GetType().Name} cannot be a configuration for editor {_editor.Alias}, expecting.", nameof(value)); + if (!_editor?.GetConfigurationEditor().IsConfiguration(value) ?? true) + throw new ArgumentException($"Value of type {value.GetType().Name} cannot be a configuration for editor {_editor?.Alias}, expecting.", nameof(value)); // extract database type from configuration object, if appropriate if (value is IConfigureValueType valueTypeConfiguration) @@ -182,7 +182,7 @@ namespace Umbraco.Cms.Core.Models { try { - return capturedEditor.GetConfigurationEditor().FromDatabase(capturedConfiguration, _serializer); + return capturedEditor?.GetConfigurationEditor().FromDatabase(capturedConfiguration, _serializer); } catch (Exception e) { diff --git a/src/Umbraco.Core/Models/Entities/EntityBase.cs b/src/Umbraco.Core/Models/Entities/EntityBase.cs index 476dd00bab..57b9eeae1f 100644 --- a/src/Umbraco.Core/Models/Entities/EntityBase.cs +++ b/src/Umbraco.Core/Models/Entities/EntityBase.cs @@ -82,7 +82,7 @@ namespace Umbraco.Cms.Core.Models.Entities _hasIdentity = false; } - public virtual bool Equals(EntityBase other) + public virtual bool Equals(EntityBase? other) { return other != null && (ReferenceEquals(this, other) || SameIdentityAs(other)); } diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs index 674bc9aa68..07fd44397b 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Core/Models/IContentBase.cs @@ -124,7 +124,7 @@ namespace Umbraco.Cms.Core.Models /// Sets the (edited) value of a Property /// /// Values 'null' and 'empty' are equivalent for culture and segment. - void SetValue(string propertyTypeAlias, object value, string? culture = null, string? segment = null); + void SetValue(string propertyTypeAlias, object? value, string? culture = null, string? segment = null); } } diff --git a/src/Umbraco.Core/Models/IDataType.cs b/src/Umbraco.Core/Models/IDataType.cs index d0819b9fae..2fdc67dfcc 100644 --- a/src/Umbraco.Core/Models/IDataType.cs +++ b/src/Umbraco.Core/Models/IDataType.cs @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Models /// /// Gets or sets the property editor. /// - IDataEditor Editor { get; set; } + IDataEditor? Editor { get; set; } /// /// Gets the property editor alias. diff --git a/src/Umbraco.Core/Models/IDataValueEditor.cs b/src/Umbraco.Core/Models/IDataValueEditor.cs index 48aa9c1b69..fb15fa530d 100644 --- a/src/Umbraco.Core/Models/IDataValueEditor.cs +++ b/src/Umbraco.Core/Models/IDataValueEditor.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.Models /// /// Gets the editor view. /// - string View { get; } + string? View { get; } /// /// Gets the type of the value. @@ -54,12 +54,12 @@ namespace Umbraco.Cms.Core.Models /// /// Converts a value posted by the editor to a property value. /// - object FromEditor(ContentPropertyData editorValue, object currentValue); + object? FromEditor(ContentPropertyData editorValue, object currentValue); /// /// Converts a property value to a value for the editor. /// - object ToEditor(IProperty property, string? culture = null, string? segment = null); + object? ToEditor(IProperty property, string? culture = null, string? segment = null); // TODO: / deal with this when unplugging the xml cache // why property vs propertyType? services should be injected! etc... diff --git a/src/Umbraco.Core/Models/IDomain.cs b/src/Umbraco.Core/Models/IDomain.cs index d855c5aa1b..f9d90dd9eb 100644 --- a/src/Umbraco.Core/Models/IDomain.cs +++ b/src/Umbraco.Core/Models/IDomain.cs @@ -12,6 +12,6 @@ namespace Umbraco.Cms.Core.Models /// /// Readonly value of the language ISO code for the domain /// - string LanguageIsoCode { get; } + string? LanguageIsoCode { get; } } } diff --git a/src/Umbraco.Core/Models/IMediaUrlGenerator.cs b/src/Umbraco.Core/Models/IMediaUrlGenerator.cs index 0119f1bd24..4565117dfd 100644 --- a/src/Umbraco.Core/Models/IMediaUrlGenerator.cs +++ b/src/Umbraco.Core/Models/IMediaUrlGenerator.cs @@ -13,6 +13,6 @@ namespace Umbraco.Cms.Core.Models /// /// True if a media path was returned /// - bool TryGetMediaPath(string propertyEditorAlias, object value, out string mediaPath); + bool TryGetMediaPath(string? propertyEditorAlias, object? value, out string? mediaPath); } } diff --git a/src/Umbraco.Core/Models/IProperty.cs b/src/Umbraco.Core/Models/IProperty.cs index 0b9ecffe46..9ed37c34e1 100644 --- a/src/Umbraco.Core/Models/IProperty.cs +++ b/src/Umbraco.Core/Models/IProperty.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.Models /// /// Returns the PropertyType, which this Property is based on /// - IPropertyType? PropertyType { get; } + IPropertyType PropertyType { get; } /// /// Gets the list of values. diff --git a/src/Umbraco.Core/Models/IPropertyCollection.cs b/src/Umbraco.Core/Models/IPropertyCollection.cs index 3997856ae7..5d18de568e 100644 --- a/src/Umbraco.Core/Models/IPropertyCollection.cs +++ b/src/Umbraco.Core/Models/IPropertyCollection.cs @@ -5,7 +5,7 @@ namespace Umbraco.Cms.Core.Models { public interface IPropertyCollection : IEnumerable, IDeepCloneable, INotifyCollectionChanged { - bool TryGetValue(string propertyTypeAlias, out IProperty property); + bool TryGetValue(string propertyTypeAlias, out IProperty? property); bool Contains(string key); /// @@ -21,12 +21,12 @@ namespace Umbraco.Cms.Core.Models /// /// Gets the property with the specified alias. /// - IProperty this[string name] { get; } + IProperty? this[string name] { get; } /// /// Gets the property at the specified index. /// - IProperty this[int index] { get; } + IProperty? this[int index] { get; } /// /// Adds or updates a property. diff --git a/src/Umbraco.Core/Models/Mapping/ContentPropertyBasicMapper.cs b/src/Umbraco.Core/Models/Mapping/ContentPropertyBasicMapper.cs index 0b4ade6328..4becc8f21a 100644 --- a/src/Umbraco.Core/Models/Mapping/ContentPropertyBasicMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/ContentPropertyBasicMapper.cs @@ -34,13 +34,13 @@ namespace Umbraco.Cms.Core.Models.Mapping /// public virtual void Map(IProperty property, TDestination dest, MapperContext context) { - var editor = _propertyEditors[property.PropertyType.PropertyEditorAlias]; + var editor = property.PropertyType is not null ? _propertyEditors[property.PropertyType.PropertyEditorAlias] : null; if (editor == null) { _logger.LogError( - new NullReferenceException("The property editor with alias " + property.PropertyType.PropertyEditorAlias + " does not exist"), + new NullReferenceException("The property editor with alias " + property.PropertyType?.PropertyEditorAlias + " does not exist"), "No property editor '{PropertyEditorAlias}' found, converting to a Label", - property.PropertyType.PropertyEditorAlias); + property.PropertyType?.PropertyEditorAlias); editor = _propertyEditors[Constants.PropertyEditors.Aliases.Label]; @@ -52,7 +52,7 @@ namespace Umbraco.Cms.Core.Models.Mapping dest.Alias = property.Alias; dest.PropertyEditor = editor; dest.Editor = editor.Alias; - dest.DataTypeKey = property.PropertyType.DataTypeKey; + dest.DataTypeKey = property.PropertyType!.DataTypeKey; // if there's a set of property aliases specified, we will check if the current property's value should be mapped. // if it isn't one of the ones specified in 'includeProperties', we will just return the result without mapping the Value. diff --git a/src/Umbraco.Core/Models/Mapping/ContentPropertyDisplayMapper.cs b/src/Umbraco.Core/Models/Mapping/ContentPropertyDisplayMapper.cs index 86d0d37f58..7cc409cae8 100644 --- a/src/Umbraco.Core/Models/Mapping/ContentPropertyDisplayMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/ContentPropertyDisplayMapper.cs @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.Models.Mapping { base.Map(originalProp, dest, context); - var config = DataTypeService.GetDataType(originalProp.PropertyType.DataTypeId).Configuration; + var config = DataTypeService.GetDataType(originalProp.PropertyType?.DataTypeId).Configuration; // TODO: IDataValueEditor configuration - general issue // GetValueEditor() returns a non-configured IDataValueEditor @@ -42,16 +42,16 @@ namespace Umbraco.Cms.Core.Models.Mapping //set the display properties after mapping dest.Alias = originalProp.Alias; - dest.Description = originalProp.PropertyType.Description; - dest.Label = originalProp.PropertyType.Name; + dest.Description = originalProp.PropertyType?.Description; + dest.Label = originalProp.PropertyType?.Name; dest.HideLabel = valEditor?.HideLabel ?? false; - dest.LabelOnTop = originalProp.PropertyType.LabelOnTop; + dest.LabelOnTop = originalProp.PropertyType?.LabelOnTop; //add the validation information - dest.Validation.Mandatory = originalProp.PropertyType.Mandatory; - dest.Validation.MandatoryMessage = originalProp.PropertyType.MandatoryMessage; - dest.Validation.Pattern = originalProp.PropertyType.ValidationRegExp; - dest.Validation.PatternMessage = originalProp.PropertyType.ValidationRegExpMessage; + dest.Validation.Mandatory = originalProp.PropertyType?.Mandatory; + dest.Validation.MandatoryMessage = originalProp.PropertyType?.MandatoryMessage; + dest.Validation.Pattern = originalProp.PropertyType?.ValidationRegExp; + dest.Validation.PatternMessage = originalProp.PropertyType?.ValidationRegExpMessage; if (dest.PropertyEditor == null) { diff --git a/src/Umbraco.Core/Models/Mapping/ContentPropertyDtoMapper.cs b/src/Umbraco.Core/Models/Mapping/ContentPropertyDtoMapper.cs index 056fb8e619..ceae3c7fcb 100644 --- a/src/Umbraco.Core/Models/Mapping/ContentPropertyDtoMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/ContentPropertyDtoMapper.cs @@ -19,14 +19,14 @@ namespace Umbraco.Cms.Core.Models.Mapping { base.Map(property, dest, context); - dest.IsRequired = property.PropertyType.Mandatory; - dest.IsRequiredMessage = property.PropertyType.MandatoryMessage; - dest.ValidationRegExp = property.PropertyType.ValidationRegExp; - dest.ValidationRegExpMessage = property.PropertyType.ValidationRegExpMessage; - dest.Description = property.PropertyType.Description; - dest.Label = property.PropertyType.Name; - dest.DataType = DataTypeService.GetDataType(property.PropertyType.DataTypeId); - dest.LabelOnTop = property.PropertyType.LabelOnTop; + dest.IsRequired = property.PropertyType?.Mandatory; + dest.IsRequiredMessage = property.PropertyType?.MandatoryMessage; + dest.ValidationRegExp = property.PropertyType?.ValidationRegExp; + dest.ValidationRegExpMessage = property.PropertyType?.ValidationRegExpMessage; + dest.Description = property.PropertyType?.Description; + dest.Label = property.PropertyType?.Name; + dest.DataType = DataTypeService.GetDataType(property.PropertyType?.DataTypeId); + dest.LabelOnTop = property.PropertyType?.LabelOnTop; } } } diff --git a/src/Umbraco.Core/Models/Mapping/DataTypeMapDefinition.cs b/src/Umbraco.Core/Models/Mapping/DataTypeMapDefinition.cs index d362016dbb..f2a0cb5140 100644 --- a/src/Umbraco.Core/Models/Mapping/DataTypeMapDefinition.cs +++ b/src/Umbraco.Core/Models/Mapping/DataTypeMapDefinition.cs @@ -90,7 +90,7 @@ namespace Umbraco.Cms.Core.Models.Mapping if (!_propertyEditors.TryGet(source.EditorAlias, out var editor)) return; - target.Alias = editor.Alias; + target.Alias = editor!.Alias; target.Group = editor.Group; target.Icon = editor.Icon; } @@ -113,7 +113,7 @@ namespace Umbraco.Cms.Core.Models.Mapping if (!_propertyEditors.TryGet(source.EditorAlias, out var editor)) return; - target.Alias = editor.Alias; + target.Alias = editor!.Alias; target.Group = editor.Group; target.Icon = editor.Icon; } @@ -146,7 +146,7 @@ namespace Umbraco.Cms.Core.Models.Mapping if (string.IsNullOrWhiteSpace(dataType.EditorAlias) || !_propertyEditors.TryGet(dataType.EditorAlias, out var editor)) throw new InvalidOperationException($"Could not find a property editor with alias \"{dataType.EditorAlias}\"."); - var configurationEditor = editor.GetConfigurationEditor(); + var configurationEditor = editor!.GetConfigurationEditor(); var fields = context.MapEnumerable(configurationEditor.Fields); var configurationDictionary = configurationEditor.ToConfigurationEditor(dataType.Configuration); @@ -155,7 +155,7 @@ namespace Umbraco.Cms.Core.Models.Mapping return fields; } - private void MapConfigurationFields(IDataType? dataType, List fields, IDictionary configuration) + private void MapConfigurationFields(IDataType? dataType, List fields, IDictionary? configuration) { if (fields == null) throw new ArgumentNullException(nameof(fields)); if (configuration == null) throw new ArgumentNullException(nameof(configuration)); @@ -164,13 +164,13 @@ namespace Umbraco.Cms.Core.Models.Mapping foreach (var field in fields.ToList()) { //filter out the not-supported pre-values for built-in data types - if (dataType != null && dataType.IsBuildInDataType() && field.Key.InvariantEquals(Constants.DataTypes.ReservedPreValueKeys.IgnoreUserStartNodes)) + if (dataType != null && dataType.IsBuildInDataType() && (field.Key?.InvariantEquals(Constants.DataTypes.ReservedPreValueKeys.IgnoreUserStartNodes) ?? false)) { fields.Remove(field); continue; } - if (configuration.TryGetValue(field.Key, out var value)) + if (field.Key is not null && configuration.TryGetValue(field.Key, out var value)) { field.Value = value; } @@ -188,7 +188,7 @@ namespace Umbraco.Cms.Core.Models.Mapping throw new InvalidOperationException($"Could not find property editor \"{source.EditorAlias}\"."); // TODO: what about source.PropertyEditor? can we get the configuration here? 'cos it may change the storage type?! - var valueType = editor.GetValueEditor().ValueType; + var valueType = editor!.GetValueEditor().ValueType; return ValueTypes.ToStorageType(valueType); } diff --git a/src/Umbraco.Core/Models/Mapping/MacroMapDefinition.cs b/src/Umbraco.Core/Models/Mapping/MacroMapDefinition.cs index 24dbe35d37..115647de7a 100644 --- a/src/Umbraco.Core/Models/Mapping/MacroMapDefinition.cs +++ b/src/Umbraco.Core/Models/Mapping/MacroMapDefinition.cs @@ -72,7 +72,7 @@ namespace Umbraco.Cms.Core.Models.Mapping _logger.LogWarning("Could not resolve a parameter editor with alias {PropertyEditorAlias}, a textbox will be rendered in it's place", source.EditorAlias); } - target.View = paramEditor.GetValueEditor().View; + target.View = paramEditor?.GetValueEditor().View; // sets the parameter configuration to be the default configuration editor's configuration, // ie configurationEditor.DefaultConfigurationObject, prepared for the value editor, ie @@ -80,8 +80,8 @@ namespace Umbraco.Cms.Core.Models.Mapping // on editors, ToValueEditor expects the actual strongly typed configuration - not the // dictionary thing returned by DefaultConfiguration - var configurationEditor = paramEditor.GetConfigurationEditor(); - target.Configuration = configurationEditor.ToValueEditor(configurationEditor.DefaultConfigurationObject); + var configurationEditor = paramEditor?.GetConfigurationEditor(); + target.Configuration = configurationEditor?.ToValueEditor(configurationEditor.DefaultConfigurationObject); } } } diff --git a/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs index 83398e9951..4636b81e7e 100644 --- a/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/MemberTabsAndPropertiesMapper.cs @@ -167,9 +167,9 @@ namespace Umbraco.Cms.Core.Models.Mapping // create a dictionary of all roles (except internal roles) + "false" var result = _memberGroupService.GetAll() - .Select(x => x.Name) + .Select(x => x.Name!) // if a role starts with __umbracoRole we won't show it as it's an internal role used for public access - .Where(x => x.StartsWith(Constants.Conventions.Member.InternalRolePrefix) == false) + .Where(x => x?.StartsWith(Constants.Conventions.Member.InternalRolePrefix) == false) .OrderBy(x => x, StringComparer.OrdinalIgnoreCase) .ToDictionary(x => x, x => false); @@ -204,7 +204,7 @@ namespace Umbraco.Cms.Core.Models.Mapping Alias = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}doctype", Label = _localizedTextService.Localize("content","membertype"), Value = _localizedTextService.UmbracoDictionaryTranslate(CultureDictionary, member.ContentType.Name), - View = _propertyEditorCollection[Constants.PropertyEditors.Aliases.Label].GetValueEditor().View + View = _propertyEditorCollection[Constants.PropertyEditors.Aliases.Label]?.GetValueEditor().View }, GetLoginProperty(member, _localizedTextService), new ContentPropertyDisplay diff --git a/src/Umbraco.Core/Models/Mapping/PropertyTypeGroupMapper.cs b/src/Umbraco.Core/Models/Mapping/PropertyTypeGroupMapper.cs index d130f17d66..57142db213 100644 --- a/src/Umbraco.Core/Models/Mapping/PropertyTypeGroupMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/PropertyTypeGroupMapper.cs @@ -225,7 +225,7 @@ namespace Umbraco.Cms.Core.Models.Mapping var config = propertyEditor == null ? new Dictionary() - : dataType.Editor.GetConfigurationEditor().ToConfigurationEditor(dataType.Configuration); + : dataType.Editor?.GetConfigurationEditor().ToConfigurationEditor(dataType.Configuration); mappedProperties.Add(new TPropertyType { diff --git a/src/Umbraco.Core/Models/Mapping/TabsAndPropertiesMapper.cs b/src/Umbraco.Core/Models/Mapping/TabsAndPropertiesMapper.cs index a3faac8588..d42e5f69df 100644 --- a/src/Umbraco.Core/Models/Mapping/TabsAndPropertiesMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/TabsAndPropertiesMapper.cs @@ -83,7 +83,7 @@ namespace Umbraco.Cms.Core.Models.Mapping /// protected virtual List MapProperties(IContentBase content, List properties, MapperContext context) { - return context.MapEnumerable(properties.OrderBy(x => x.PropertyType.SortOrder)); + return context.MapEnumerable(properties.OrderBy(x => x.PropertyType?.SortOrder)); } } diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs index 05213f68b5..8b59980974 100644 --- a/src/Umbraco.Core/Models/Member.cs +++ b/src/Umbraco.Core/Models/Member.cs @@ -265,9 +265,9 @@ namespace Umbraco.Cms.Core.Models if (a.Success == false) return a.Result; - return Properties[Constants.Conventions.Member.Comments].GetValue() == null + return Properties[Constants.Conventions.Member.Comments]?.GetValue() == null ? string.Empty - : Properties[Constants.Conventions.Member.Comments].GetValue()?.ToString(); + : Properties[Constants.Conventions.Member.Comments]?.GetValue()?.ToString(); } set { @@ -276,7 +276,7 @@ namespace Umbraco.Cms.Core.Models nameof(Comments)) == false) return; - Properties[Constants.Conventions.Member.Comments].SetValue(value); + Properties[Constants.Conventions.Member.Comments]?.SetValue(value); } } @@ -297,12 +297,12 @@ namespace Umbraco.Cms.Core.Models true); if (a.Success == false) return a.Result; - if (Properties[Constants.Conventions.Member.IsApproved].GetValue() == null) + if (Properties[Constants.Conventions.Member.IsApproved]?.GetValue() == null) return true; - var tryConvert = Properties[Constants.Conventions.Member.IsApproved].GetValue().TryConvertTo(); - if (tryConvert.Success ?? false) + var tryConvert = Properties[Constants.Conventions.Member.IsApproved]?.GetValue().TryConvertTo(); + if (tryConvert?.Success ?? false) { - return tryConvert.Result; + return tryConvert?.Result ?? false; } //if the property exists but it cannot be converted, we will assume true return true; @@ -314,7 +314,7 @@ namespace Umbraco.Cms.Core.Models nameof(IsApproved)) == false) return; - Properties[Constants.Conventions.Member.IsApproved].SetValue(value); + Properties[Constants.Conventions.Member.IsApproved]?.SetValue(value); } } @@ -333,12 +333,12 @@ namespace Umbraco.Cms.Core.Models var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsLockedOut, nameof(IsLockedOut), false); if (a.Success == false) return a.Result; - if (Properties[Constants.Conventions.Member.IsLockedOut].GetValue() == null) + if (Properties[Constants.Conventions.Member.IsLockedOut]?.GetValue() == null) return false; - var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].GetValue().TryConvertTo(); - if (tryConvert.Success ?? false) + var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut]?.GetValue().TryConvertTo(); + if (tryConvert?.Success ?? false) { - return tryConvert.Result; + return tryConvert?.Result ?? false; } return false; // TODO: Use TryConvertTo instead @@ -350,7 +350,7 @@ namespace Umbraco.Cms.Core.Models nameof(IsLockedOut)) == false) return; - Properties[Constants.Conventions.Member.IsLockedOut].SetValue(value); + Properties[Constants.Conventions.Member.IsLockedOut]?.SetValue(value); } } @@ -369,12 +369,12 @@ namespace Umbraco.Cms.Core.Models var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLoginDate, nameof(LastLoginDate), default(DateTime)); if (a.Success == false) return a.Result; - if (Properties[Constants.Conventions.Member.LastLoginDate].GetValue() == null) + if (Properties[Constants.Conventions.Member.LastLoginDate]?.GetValue() == null) return default(DateTime); - var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].GetValue().TryConvertTo(); - if (tryConvert.Success ?? false) + var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate]?.GetValue().TryConvertTo(); + if (tryConvert?.Success ?? false) { - return tryConvert.Result; + return tryConvert?.Result ?? default(DateTime); } return default(DateTime); // TODO: Use TryConvertTo instead @@ -386,7 +386,7 @@ namespace Umbraco.Cms.Core.Models nameof(LastLoginDate)) == false) return; - Properties[Constants.Conventions.Member.LastLoginDate].SetValue(value); + Properties[Constants.Conventions.Member.LastLoginDate]?.SetValue(value); } } @@ -405,12 +405,12 @@ namespace Umbraco.Cms.Core.Models var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastPasswordChangeDate, nameof(LastPasswordChangeDate), default(DateTime)); if (a.Success == false) return a.Result; - if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].GetValue() == null) + if (Properties[Constants.Conventions.Member.LastPasswordChangeDate]?.GetValue() == null) return default(DateTime); - var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].GetValue().TryConvertTo(); - if (tryConvert.Success ?? false) + var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate]?.GetValue().TryConvertTo(); + if (tryConvert?.Success ?? false) { - return tryConvert.Result; + return tryConvert?.Result ?? default(DateTime); } return default(DateTime); // TODO: Use TryConvertTo instead @@ -422,7 +422,7 @@ namespace Umbraco.Cms.Core.Models nameof(LastPasswordChangeDate)) == false) return; - Properties[Constants.Conventions.Member.LastPasswordChangeDate].SetValue(value); + Properties[Constants.Conventions.Member.LastPasswordChangeDate]?.SetValue(value); } } @@ -441,12 +441,12 @@ namespace Umbraco.Cms.Core.Models var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLockoutDate, nameof(LastLockoutDate), default(DateTime)); if (a.Success == false) return a.Result; - if (Properties[Constants.Conventions.Member.LastLockoutDate].GetValue() == null) + if (Properties[Constants.Conventions.Member.LastLockoutDate]?.GetValue() == null) return default(DateTime); - var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].GetValue().TryConvertTo(); - if (tryConvert.Success ?? false) + var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate]?.GetValue().TryConvertTo(); + if (tryConvert?.Success ?? false) { - return tryConvert.Result; + return tryConvert?.Result ?? default(DateTime); } return default(DateTime); // TODO: Use TryConvertTo instead @@ -458,7 +458,7 @@ namespace Umbraco.Cms.Core.Models nameof(LastLockoutDate)) == false) return; - Properties[Constants.Conventions.Member.LastLockoutDate].SetValue(value); + Properties[Constants.Conventions.Member.LastLockoutDate]?.SetValue(value); } } @@ -478,12 +478,12 @@ namespace Umbraco.Cms.Core.Models var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.FailedPasswordAttempts, nameof(FailedPasswordAttempts), 0); if (a.Success == false) return a.Result; - if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].GetValue() == null) + if (Properties[Constants.Conventions.Member.FailedPasswordAttempts]?.GetValue() == null) return default(int); - var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].GetValue().TryConvertTo(); - if (tryConvert.Success ?? false) + var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts]?.GetValue().TryConvertTo(); + if (tryConvert?.Success ?? false) { - return tryConvert.Result; + return tryConvert?.Result ?? default(int); } return default(int); // TODO: Use TryConvertTo instead @@ -495,7 +495,7 @@ namespace Umbraco.Cms.Core.Models nameof(FailedPasswordAttempts)) == false) return; - Properties[Constants.Conventions.Member.FailedPasswordAttempts].SetValue(value); + Properties[Constants.Conventions.Member.FailedPasswordAttempts]?.SetValue(value); } } diff --git a/src/Umbraco.Core/Models/Membership/UserProfile.cs b/src/Umbraco.Core/Models/Membership/UserProfile.cs index 752dab2498..aca757b317 100644 --- a/src/Umbraco.Core/Models/Membership/UserProfile.cs +++ b/src/Umbraco.Core/Models/Membership/UserProfile.cs @@ -4,14 +4,14 @@ namespace Umbraco.Cms.Core.Models.Membership { public class UserProfile : IProfile, IEquatable { - public UserProfile(int id, string name) + public UserProfile(int id, string? name) { Id = id; Name = name; } public int Id { get; private set; } - public string Name { get; private set; } + public string? Name { get; private set; } public bool Equals(UserProfile? other) { diff --git a/src/Umbraco.Core/Models/PartialViewMacroModelExtensions.cs b/src/Umbraco.Core/Models/PartialViewMacroModelExtensions.cs index 64d26e8939..2bc1714dbd 100644 --- a/src/Umbraco.Core/Models/PartialViewMacroModelExtensions.cs +++ b/src/Umbraco.Core/Models/PartialViewMacroModelExtensions.cs @@ -21,7 +21,7 @@ namespace Umbraco.Extensions var attempt = partialViewMacroModel.MacroParameters[parameterAlias].TryConvertTo(typeof(T)); - return attempt.Success ?? false ? (T?) attempt.Result : defaultValue; + return attempt.Success ? (T?) attempt.Result : defaultValue; } /// diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 8cf58fa9be..2975b97b42 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -199,7 +199,7 @@ namespace Umbraco.Cms.Core.Models return ((IEnumerable)o).Cast().UnsortedSequenceEqual(enumerable.Cast()); return o.Equals(o1); - }, o => o.GetHashCode()); + }, o => o!.GetHashCode()); /// /// Returns the PropertyType, which this Property is based on @@ -460,21 +460,21 @@ namespace Umbraco.Cms.Core.Models if (s.IsNullOrWhiteSpace()) return true; // assume empty means null var convInt = value.TryConvertTo(); - if (convInt.Success.HasValue && convInt.Success.Value) + if (convInt.Success) { converted = convInt.Result; return true; } if (throwOnError) - ThrowTypeException(value, typeof(int), Alias); + ThrowTypeException(value, typeof(int), Alias ?? string.Empty); return false; case ValueStorageType.Decimal: if (s.IsNullOrWhiteSpace()) return true; // assume empty means null var convDecimal = value.TryConvertTo(); - if (convDecimal.Success.HasValue && convDecimal.Success.Value) + if (convDecimal.Success) { // need to normalize the value (change the scaling factor and remove trailing zeros) // because the underlying database is going to mess with the scaling factor anyways. @@ -483,21 +483,21 @@ namespace Umbraco.Cms.Core.Models } if (throwOnError) - ThrowTypeException(value, typeof(decimal), Alias); + ThrowTypeException(value, typeof(decimal), Alias ?? string.Empty); return false; case ValueStorageType.Date: if (s.IsNullOrWhiteSpace()) return true; // assume empty means null var convDateTime = value.TryConvertTo(); - if (convDateTime.Success.HasValue && convDateTime.Success.Value) + if (convDateTime.Success) { converted = convDateTime.Result; return true; } if (throwOnError) - ThrowTypeException(value, typeof(DateTime), Alias); + ThrowTypeException(value, typeof(DateTime), Alias ?? string.Empty); return false; default: diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index 593e163e03..4dc4bc05a0 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -123,7 +123,7 @@ namespace Umbraco.Cms.Core.Models { for (var i = 0; i < Count; i++) { - if (this[i].Alias.InvariantEquals(key)) + if (this[i].Alias?.InvariantEquals(key) ?? false) return i; } return -1; @@ -131,30 +131,30 @@ namespace Umbraco.Cms.Core.Models protected override string GetKeyForItem(IProperty item) { - return item.Alias; + return item.Alias!; } /// /// Gets the property with the specified PropertyType. /// - internal IProperty this[IPropertyType propertyType] + internal IProperty? this[IPropertyType propertyType] { get { - return this.FirstOrDefault(x => x.Alias.InvariantEquals(propertyType.Alias)); + return this.FirstOrDefault(x => x.Alias?.InvariantEquals(propertyType.Alias) ?? false); } } - public bool TryGetValue(string propertyTypeAlias, out IProperty property) + public bool TryGetValue(string propertyTypeAlias, out IProperty? property) { - property = this.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); + property = this.FirstOrDefault(x => x.Alias?.InvariantEquals(propertyTypeAlias) ?? false); return property != null; } /// /// Occurs when the collection changes. /// - public event NotifyCollectionChangedEventHandler CollectionChanged; + public event NotifyCollectionChangedEventHandler? CollectionChanged; public void ClearCollectionChangedEvents() => CollectionChanged = null; @@ -187,7 +187,14 @@ namespace Umbraco.Cms.Core.Models var typeAliases = propertyTypesA.Select(x => x.Alias); var remove = thisAliases.Except(typeAliases).ToArray(); foreach (var alias in remove) - Remove(alias); + { + if (alias is not null) + { + Remove(alias); + } + + } + foreach (var propertyType in propertyTypesA) Add(new Property(propertyType)); diff --git a/src/Umbraco.Core/Models/PropertyGroup.cs b/src/Umbraco.Core/Models/PropertyGroup.cs index 3c86c064e7..b5f3a36046 100644 --- a/src/Umbraco.Core/Models/PropertyGroup.cs +++ b/src/Umbraco.Core/Models/PropertyGroup.cs @@ -15,24 +15,28 @@ namespace Umbraco.Cms.Core.Models [DebuggerDisplay("Id: {Id}, Name: {Name}, Alias: {Alias}")] public class PropertyGroup : EntityBase, IEquatable { - [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "This field is for internal use only (to allow changing item keys).")] - internal PropertyGroupCollection Collection; + [SuppressMessage("Style", "IDE1006:Naming Styles", + Justification = "This field is for internal use only (to allow changing item keys).")] + internal PropertyGroupCollection? Collection; + private PropertyGroupType _type; - private string _name; + private string? _name; private string _alias; private int _sortOrder; private PropertyTypeCollection _propertyTypes; public PropertyGroup(bool isPublishing) : this(new PropertyTypeCollection(isPublishing)) - { } + { + } public PropertyGroup(PropertyTypeCollection propertyTypeCollection) { - PropertyTypes = propertyTypeCollection; + _propertyTypes = propertyTypeCollection; + _alias = string.Empty; } - private void PropertyTypesChanged(object sender, NotifyCollectionChangedEventArgs e) + private void PropertyTypesChanged(object? sender, NotifyCollectionChangedEventArgs e) { OnPropertyChanged(nameof(PropertyTypes)); } @@ -57,7 +61,7 @@ namespace Umbraco.Cms.Core.Models /// The name. /// [DataMember] - public string Name + public string? Name { get => _name; set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name)); @@ -78,7 +82,7 @@ namespace Umbraco.Cms.Core.Models // If added to a collection, ensure the key is changed before setting it (this ensures the internal lookup dictionary is updated) Collection?.ChangeKey(this, value); - SetPropertyValueAndDetectChanges(value, ref _alias, nameof(Alias)); + SetPropertyValueAndDetectChanges(value, ref _alias!, nameof(Alias)); } } @@ -128,7 +132,8 @@ namespace Umbraco.Cms.Core.Models } } - public bool Equals(PropertyGroup other) => base.Equals(other) || (other != null && Type == other.Type && Alias == other.Alias); + public bool Equals(PropertyGroup? other) => + base.Equals(other) || (other != null && Type == other.Type && Alias == other.Alias); public override int GetHashCode() => (base.GetHashCode(), Type, Alias).GetHashCode(); @@ -142,8 +147,9 @@ namespace Umbraco.Cms.Core.Models if (clonedEntity._propertyTypes != null) { clonedEntity._propertyTypes.ClearCollectionChangedEvents(); //clear this event handler if any - clonedEntity._propertyTypes = (PropertyTypeCollection) _propertyTypes.DeepClone(); //manually deep clone - clonedEntity._propertyTypes.CollectionChanged += clonedEntity.PropertyTypesChanged; //re-assign correct event handler + clonedEntity._propertyTypes = (PropertyTypeCollection)_propertyTypes!.DeepClone(); //manually deep clone + clonedEntity._propertyTypes.CollectionChanged += + clonedEntity.PropertyTypesChanged; //re-assign correct event handler } } } diff --git a/src/Umbraco.Core/Models/PropertyGroupCollection.cs b/src/Umbraco.Core/Models/PropertyGroupCollection.cs index f309600915..f248b12811 100644 --- a/src/Umbraco.Core/Models/PropertyGroupCollection.cs +++ b/src/Umbraco.Core/Models/PropertyGroupCollection.cs @@ -45,7 +45,7 @@ namespace Umbraco.Cms.Core.Models protected override void SetItem(int index, PropertyGroup item) { var oldItem = index >= 0 ? this[index] : item; - + base.SetItem(index, item); oldItem.Collection = null; @@ -133,7 +133,7 @@ namespace Umbraco.Cms.Core.Models protected override string GetKeyForItem(PropertyGroup item) => item.Alias; - public event NotifyCollectionChangedEventHandler CollectionChanged; + public event NotifyCollectionChangedEventHandler? CollectionChanged; /// /// Clears all event handlers diff --git a/src/Umbraco.Core/Models/PropertyGroupExtensions.cs b/src/Umbraco.Core/Models/PropertyGroupExtensions.cs index f8f94c06ab..bb12e1bc1b 100644 --- a/src/Umbraco.Core/Models/PropertyGroupExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyGroupExtensions.cs @@ -4,18 +4,18 @@ namespace Umbraco.Cms.Core.Models { private const char AliasSeparator = '/'; - internal static string GetLocalAlias(string alias) + internal static string? GetLocalAlias(string alias) { var lastIndex = alias?.LastIndexOf(AliasSeparator) ?? -1; if (lastIndex != -1) { - return alias.Substring(lastIndex + 1); + return alias?.Substring(lastIndex + 1); } return alias; } - internal static string GetParentAlias(string alias) + internal static string? GetParentAlias(string? alias) { var lastIndex = alias?.LastIndexOf(AliasSeparator) ?? -1; if (lastIndex == -1) @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Models return null; } - return alias.Substring(0, lastIndex); + return alias?.Substring(0, lastIndex); } /// @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.Models /// /// The local alias. /// - public static string GetLocalAlias(this PropertyGroup propertyGroup) => GetLocalAlias(propertyGroup.Alias); + public static string? GetLocalAlias(this PropertyGroup propertyGroup) => GetLocalAlias(propertyGroup.Alias); /// /// Updates the local alias. @@ -60,7 +60,7 @@ namespace Umbraco.Cms.Core.Models /// /// The parent alias. /// - public static string GetParentAlias(this PropertyGroup propertyGroup) => GetParentAlias(propertyGroup.Alias); + public static string? GetParentAlias(this PropertyGroup propertyGroup) => GetParentAlias(propertyGroup.Alias); /// /// Updates the parent alias. @@ -72,7 +72,7 @@ namespace Umbraco.Cms.Core.Models var localAlias = propertyGroup.GetLocalAlias(); if (string.IsNullOrEmpty(parentAlias)) { - propertyGroup.Alias = localAlias; + propertyGroup.Alias = localAlias!; } else { diff --git a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs index 0cfdfc8e07..6fb8669af0 100644 --- a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs @@ -17,18 +17,18 @@ namespace Umbraco.Extensions { // gets the tag configuration for a property // from the datatype configuration, and the editor tag configuration attribute - public static TagConfiguration GetTagConfiguration(this IProperty property, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService) + public static TagConfiguration? GetTagConfiguration(this IProperty property, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService) { if (property == null) throw new ArgumentNullException(nameof(property)); - var editor = propertyEditors[property.PropertyType.PropertyEditorAlias]; - var tagAttribute = editor.GetTagAttribute(); + var editor = propertyEditors[property.PropertyType?.PropertyEditorAlias]; + var tagAttribute = editor?.GetTagAttribute(); if (tagAttribute == null) return null; - var configurationObject = dataTypeService.GetDataType(property.PropertyType.DataTypeId).Configuration; + var configurationObject = dataTypeService.GetDataType(property.PropertyType?.DataTypeId).Configuration; var configuration = ConfigurationEditor.ConfigurationAs(configurationObject); - if (configuration.Delimiter == default) + if (configuration?.Delimiter == default && configuration?.Delimiter is not null) configuration.Delimiter = tagAttribute.Delimiter; return configuration; @@ -56,7 +56,7 @@ namespace Umbraco.Extensions } // assumes that parameters are consistent with the datatype configuration - private static void AssignTags(this IProperty property, IEnumerable tags, bool merge, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string culture) + private static void AssignTags(this IProperty property, IEnumerable tags, bool merge, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string? culture) { // set the property value var trimmedTags = tags.Select(x => x.Trim()).ToArray(); @@ -112,7 +112,7 @@ namespace Umbraco.Extensions } // assumes that parameters are consistent with the datatype configuration - private static void RemoveTags(this IProperty property, IEnumerable tags, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string culture) + private static void RemoveTags(this IProperty property, IEnumerable tags, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string? culture) { // already empty = nothing to do var value = property.GetValue(culture)?.ToString(); @@ -213,14 +213,14 @@ namespace Umbraco.Extensions switch (storageType) { case TagsStorageType.Csv: - var tags2 = value.ToString().Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); + var tags2 = value.ToString()!.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); property.AssignTags(tags2, false, storageType, serializer, delimiter, culture); break; case TagsStorageType.Json: try { - var tags3 = serializer.Deserialize>(value.ToString()); + var tags3 = serializer.Deserialize>(value.ToString()!); property.AssignTags(tags3 ?? Enumerable.Empty(), false, storageType, serializer, delimiter, culture); } catch (Exception ex) diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index 19abc7732b..7db1d0d2b3 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -17,19 +17,19 @@ namespace Umbraco.Cms.Core.Models { private readonly IShortStringHelper _shortStringHelper; private readonly bool _forceValueStorageType; - private string _name; + private string? _name; private string _alias; - private string _description; + private string? _description; private int _dataTypeId; private Guid _dataTypeKey; - private Lazy _propertyGroupId; + private Lazy? _propertyGroupId; private string _propertyEditorAlias; private ValueStorageType _valueStorageType; - private bool _mandatory; - private string _mandatoryMessage; + private bool? _mandatory; + private string? _mandatoryMessage; private int _sortOrder; - private string _validationRegExp; - private string _validationRegExpMessage; + private string? _validationRegExp; + private string? _validationRegExpMessage; private ContentVariation _variations; private bool _labelOnTop; @@ -47,12 +47,13 @@ namespace Umbraco.Cms.Core.Models _propertyEditorAlias = dataType.EditorAlias; _valueStorageType = dataType.DatabaseType; _variations = ContentVariation.Nothing; + _alias = string.Empty; } /// /// Initializes a new instance of the class. /// - public PropertyType(IShortStringHelper shortStringHelper, IDataType dataType, string? propertyTypeAlias) + public PropertyType(IShortStringHelper shortStringHelper, IDataType dataType, string propertyTypeAlias) : this(shortStringHelper, dataType) { _alias = SanitizeAlias(propertyTypeAlias); @@ -79,13 +80,13 @@ namespace Umbraco.Cms.Core.Models /// /// Set to true to force the value storage type. Values assigned to /// the property, eg from the underlying datatype, will be ignored. - public PropertyType(IShortStringHelper shortStringHelper, string propertyEditorAlias, ValueStorageType valueStorageType, bool forceValueStorageType, string propertyTypeAlias = null) + public PropertyType(IShortStringHelper shortStringHelper, string propertyEditorAlias, ValueStorageType valueStorageType, bool forceValueStorageType, string? propertyTypeAlias = null) { _shortStringHelper = shortStringHelper; _propertyEditorAlias = propertyEditorAlias; _valueStorageType = valueStorageType; _forceValueStorageType = forceValueStorageType; - _alias = propertyTypeAlias == null ? null : SanitizeAlias(propertyTypeAlias); + _alias = propertyTypeAlias == null ? string.Empty : SanitizeAlias(propertyTypeAlias); _variations = ContentVariation.Nothing; } @@ -109,7 +110,7 @@ namespace Umbraco.Cms.Core.Models /// [DataMember] - public string Name + public string? Name { get => _name; set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name)); @@ -120,12 +121,12 @@ namespace Umbraco.Cms.Core.Models public virtual string Alias { get => _alias; - set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, nameof(Alias)); + set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias!, nameof(Alias)); } /// [DataMember] - public string Description + public string? Description { get => _description; set => SetPropertyValueAndDetectChanges(value, ref _description, nameof(Description)); @@ -151,7 +152,7 @@ namespace Umbraco.Cms.Core.Models public string PropertyEditorAlias { get => _propertyEditorAlias; - set => SetPropertyValueAndDetectChanges(value, ref _propertyEditorAlias, nameof(PropertyEditorAlias)); + set => SetPropertyValueAndDetectChanges(value, ref _propertyEditorAlias!, nameof(PropertyEditorAlias)); } /// @@ -169,7 +170,7 @@ namespace Umbraco.Cms.Core.Models /// [DataMember] [DoNotClone] - public Lazy PropertyGroupId + public Lazy? PropertyGroupId { get => _propertyGroupId; set => SetPropertyValueAndDetectChanges(value, ref _propertyGroupId, nameof(PropertyGroupId)); @@ -177,7 +178,7 @@ namespace Umbraco.Cms.Core.Models /// [DataMember] - public bool Mandatory + public bool? Mandatory { get => _mandatory; set => SetPropertyValueAndDetectChanges(value, ref _mandatory, nameof(Mandatory)); @@ -186,7 +187,7 @@ namespace Umbraco.Cms.Core.Models /// [DataMember] - public string MandatoryMessage + public string? MandatoryMessage { get => _mandatoryMessage; set => SetPropertyValueAndDetectChanges(value, ref _mandatoryMessage, nameof(MandatoryMessage)); @@ -210,7 +211,7 @@ namespace Umbraco.Cms.Core.Models /// [DataMember] - public string ValidationRegExp + public string? ValidationRegExp { get => _validationRegExp; set => SetPropertyValueAndDetectChanges(value, ref _validationRegExp, nameof(ValidationRegExp)); @@ -221,7 +222,7 @@ namespace Umbraco.Cms.Core.Models /// Gets or sets the custom validation message used when a pattern for this PropertyType must be matched /// [DataMember] - public string ValidationRegExpMessage + public string? ValidationRegExpMessage { get => _validationRegExpMessage; set => SetPropertyValueAndDetectChanges(value, ref _validationRegExpMessage, nameof(ValidationRegExpMessage)); @@ -235,7 +236,7 @@ namespace Umbraco.Cms.Core.Models } /// - public bool SupportsVariation(string culture, string segment, bool wildcards = false) + public bool SupportsVariation(string? culture, string? segment, bool wildcards = false) { // exact validation: cannot accept a 'null' culture if the property type varies // by culture, and likewise for segment @@ -246,21 +247,21 @@ namespace Umbraco.Cms.Core.Models /// /// Sanitizes a property type alias. /// - private string? SanitizeAlias(string? value) + private string SanitizeAlias(string value) { //NOTE: WE are doing this because we don't want to do a ToSafeAlias when the alias is the special case of // being prefixed with Constants.PropertyEditors.InternalGenericPropertiesPrefix // which is used internally - return value?.StartsWith(Constants.PropertyEditors.InternalGenericPropertiesPrefix) ?? false + return value.StartsWith(Constants.PropertyEditors.InternalGenericPropertiesPrefix) ? value - : value?.ToCleanString(_shortStringHelper, CleanStringType.Alias | CleanStringType.UmbracoCase); + : value.ToCleanString(_shortStringHelper, CleanStringType.Alias | CleanStringType.UmbracoCase); } /// public bool Equals(PropertyType? other) { - return other != null && (base.Equals(other) || Alias.InvariantEquals(other.Alias)); + return other != null && (base.Equals(other) || (Alias?.InvariantEquals(other.Alias) ?? false)); } /// @@ -270,10 +271,10 @@ namespace Umbraco.Cms.Core.Models int baseHash = base.GetHashCode(); //Get hash code for the Alias field. - int hashAlias = Alias.ToLowerInvariant().GetHashCode(); + int? hashAlias = Alias?.ToLowerInvariant().GetHashCode(); //Calculate the hash code for the product. - return baseHash ^ hashAlias; + return baseHash ^ hashAlias ?? baseHash; } /// diff --git a/src/Umbraco.Core/Models/PropertyTypeCollection.cs b/src/Umbraco.Core/Models/PropertyTypeCollection.cs index f63e23ae02..96133f6677 100644 --- a/src/Umbraco.Core/Models/PropertyTypeCollection.cs +++ b/src/Umbraco.Core/Models/PropertyTypeCollection.cs @@ -31,6 +31,11 @@ namespace Umbraco.Cms.Core.Models public bool SupportsPublishing { get; } + // This baseclass calling is needed, else compiler will complain about nullability + + /// + public bool IsReadOnly => ((ICollection)this).IsReadOnly; + /// /// Resets the collection to only contain the instances referenced in the parameter. /// @@ -115,9 +120,9 @@ namespace Umbraco.Cms.Core.Models /// /// /// - private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + private void Item_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { - var propType = (IPropertyType)sender; + var propType = (IPropertyType?)sender; OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, propType, propType)); } @@ -149,10 +154,10 @@ namespace Umbraco.Cms.Core.Models protected override string GetKeyForItem(IPropertyType item) { - return item.Alias; + return item.Alias!; } - public event NotifyCollectionChangedEventHandler CollectionChanged; + public event NotifyCollectionChangedEventHandler? CollectionChanged; /// /// Clears all event handlers diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedElement.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedElement.cs index f70fb9db7b..8f74201002 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedElement.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedElement.cs @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// /// Contains one IPublishedProperty for each property defined for the content type, including /// inherited properties. Some properties may have no value. - IEnumerable Properties { get; } + IEnumerable? Properties { get; } /// /// Gets a property identified by its alias. @@ -45,7 +45,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// otherwise return a property -- that may have no value (ie HasValue is false). /// The alias is case-insensitive. /// - IPublishedProperty GetProperty(string alias); + IPublishedProperty? GetProperty(string alias); #endregion } diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs index 0d7440ff9c..6ebf1c6707 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// /// The model type alias. /// A List{T} of the strongly-typed model, exposed as an IList. - IList CreateModelList(string alias); + IList? CreateModelList(string alias); /// /// Maps a CLR type that may contain model types, to an actual CLR type. diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs index f81acca36f..2f30e16bdb 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedPropertyType.cs @@ -47,7 +47,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// Determines whether a value is an actual value, or not a value. /// /// Used by property.HasValue and, for instance, in fallback scenarios. - bool? IsValue(object value, PropertyValueLevel level); + bool? IsValue(object? value, PropertyValueLevel level); /// /// Gets the property cache level. @@ -61,7 +61,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// The source value. /// A value indicating whether content should be considered draft. /// The intermediate value. - object ConvertSourceToInter(IPublishedElement owner, object source, bool preview); + object? ConvertSourceToInter(IPublishedElement owner, object? source, bool preview); /// /// Converts the intermediate value into the object value. @@ -71,7 +71,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// The intermediate value. /// A value indicating whether content should be considered draft. /// The object value. - object ConvertInterToObject(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview); + object? ConvertInterToObject(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview); /// /// Converts the intermediate value into the XPath value. @@ -84,7 +84,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// /// The XPath value can be either a string or an XPathNavigator. /// - object? ConvertInterToXPath(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview); + object? ConvertInterToXPath(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview); /// /// Gets the property model CLR type. diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs index abd933ae01..3cf1f3c512 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs @@ -122,10 +122,10 @@ namespace Umbraco.Cms.Core.Models.PublishedContent #region Properties /// - public virtual IEnumerable Properties => _content.Properties; + public virtual IEnumerable? Properties => _content.Properties; /// - public virtual IPublishedProperty GetProperty(string alias) + public virtual IPublishedProperty? GetProperty(string alias) { return _content.GetProperty(alias); } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedElementWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedElementWrapped.cs index 5f9564d176..358dd4014a 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedElementWrapped.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedElementWrapped.cs @@ -37,9 +37,9 @@ namespace Umbraco.Cms.Core.Models.PublishedContent public Guid Key => _content.Key; /// - public IEnumerable Properties => _content.Properties; + public IEnumerable? Properties => _content.Properties; /// - public IPublishedProperty GetProperty(string alias) => _content.GetProperty(alias); + public IPublishedProperty? GetProperty(string alias) => _content.GetProperty(alias); } } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs index 94aae97385..3c8ae6b3d2 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs @@ -104,7 +104,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public IList CreateModelList(string alias) + public IList? CreateModelList(string alias) { // fail fast if (_modelInfos == null) @@ -118,7 +118,8 @@ namespace Umbraco.Cms.Core.Models.PublishedContent var listType = typeof(List<>).MakeGenericType(modelInfo.ModelType); ctor = modelInfo.ListCtor = ReflectionUtilities.EmitConstructor>(declaring: listType); - return ctor(); + if(ctor is not null) return ctor(); + return null; } /// diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs index c8b5773106..002848a758 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs @@ -179,7 +179,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public bool? IsValue(object value, PropertyValueLevel level) + public bool? IsValue(object? value, PropertyValueLevel level) { if (!_initialized) Initialize(); @@ -202,7 +202,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public object ConvertSourceToInter(IPublishedElement owner, object source, bool preview) + public object? ConvertSourceToInter(IPublishedElement owner, object? source, bool preview) { if (!_initialized) Initialize(); @@ -213,7 +213,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public object ConvertInterToObject(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public object? ConvertInterToObject(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { if (!_initialized) Initialize(); @@ -224,7 +224,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent } /// - public object? ConvertInterToXPath(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public object? ConvertInterToXPath(IPublishedElement owner, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { if (!_initialized) Initialize(); diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedValueFallback.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedValueFallback.cs index 811d230ef9..ed8acf2736 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedValueFallback.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedValueFallback.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent /// public class PublishedValueFallback : IPublishedValueFallback { - private readonly ILocalizationService _localizationService; + private readonly ILocalizationService? _localizationService; private readonly IVariationContextAccessor _variationContextAccessor; /// @@ -197,7 +197,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent var visited = new HashSet(); - var language = culture is not null ? _localizationService.GetLanguageByIsoCode(culture) : null; + var language = culture is not null ? _localizationService?.GetLanguageByIsoCode(culture) : null; if (language == null) return false; while (true) @@ -208,7 +208,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent if (visited.Contains(language2Id)) return false; visited.Add(language2Id); - var language2 = _localizationService.GetLanguageById(language2Id); + var language2 = _localizationService?.GetLanguageById(language2Id); if (language2 == null) return false; var culture2 = language2.IsoCode; @@ -231,7 +231,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent var visited = new HashSet(); - var language = culture is not null ? _localizationService.GetLanguageByIsoCode(culture) : null; + var language = culture is not null ? _localizationService?.GetLanguageByIsoCode(culture) : null; if (language == null) return false; while (true) @@ -242,7 +242,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent if (visited.Contains(language2Id)) return false; visited.Add(language2Id); - var language2 = _localizationService.GetLanguageById(language2Id); + var language2 = _localizationService?.GetLanguageById(language2Id); if (language2 == null) return false; var culture2 = language2.IsoCode; @@ -268,7 +268,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent // TODO: _localizationService.GetXxx() is expensive, it deep clones objects // we want _localizationService.GetReadOnlyXxx() returning IReadOnlyLanguage which cannot be saved back = no need to clone - var language = culture is not null ? _localizationService.GetLanguageByIsoCode(culture) : null; + var language = culture is not null ? _localizationService?.GetLanguageByIsoCode(culture) : null; if (language == null) return false; while (true) @@ -279,7 +279,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent if (visited.Contains(language2Id)) return false; visited.Add(language2Id); - var language2 = _localizationService.GetLanguageById(language2Id); + var language2 = _localizationService?.GetLanguageById(language2Id); if (language2 == null) return false; var culture2 = language2.IsoCode; diff --git a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs b/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs index 9e52adc07f..2ae0ce6c1d 100644 --- a/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs +++ b/src/Umbraco.Core/Models/PublishedContent/RawValueProperty.cs @@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core.Models.PublishedContent public class RawValueProperty : PublishedPropertyBase { private readonly object _sourceValue; //the value in the db - private readonly Lazy _objectValue; + private readonly Lazy _objectValue; private readonly Lazy _xpathValue; // RawValueProperty does not (yet?) support variants, @@ -46,9 +46,9 @@ namespace Umbraco.Cms.Core.Models.PublishedContent _sourceValue = sourceValue; - var interValue = new Lazy(() => PropertyType.ConvertSourceToInter(content, _sourceValue, isPreviewing)); - _objectValue = new Lazy(() => PropertyType.ConvertInterToObject(content, PropertyCacheLevel.Unknown, interValue.Value, isPreviewing)); - _xpathValue = new Lazy(() => PropertyType.ConvertInterToXPath(content, PropertyCacheLevel.Unknown, interValue.Value, isPreviewing)); + var interValue = new Lazy(() => PropertyType.ConvertSourceToInter(content, _sourceValue, isPreviewing)); + _objectValue = new Lazy(() => PropertyType.ConvertInterToObject(content, PropertyCacheLevel.Unknown, interValue?.Value, isPreviewing)); + _xpathValue = new Lazy(() => PropertyType.ConvertInterToXPath(content, PropertyCacheLevel.Unknown, interValue?.Value, isPreviewing)); } } } diff --git a/src/Umbraco.Core/Models/RelationType.cs b/src/Umbraco.Core/Models/RelationType.cs index 87c2084af7..2b59b52262 100644 --- a/src/Umbraco.Core/Models/RelationType.cs +++ b/src/Umbraco.Core/Models/RelationType.cs @@ -40,7 +40,7 @@ namespace Umbraco.Cms.Core.Models /// Gets or sets the Name of the RelationType /// [DataMember] - public string Name + public string? Name { get => _name; set => SetPropertyValueAndDetectChanges(value, ref _name!, nameof(Name)); diff --git a/src/Umbraco.Core/Models/Stylesheet.cs b/src/Umbraco.Core/Models/Stylesheet.cs index 1dc386f510..18f9420d75 100644 --- a/src/Umbraco.Core/Models/Stylesheet.cs +++ b/src/Umbraco.Core/Models/Stylesheet.cs @@ -104,7 +104,7 @@ namespace Umbraco.Cms.Core.Models /// /// Gets or sets the Content of a File /// - public override string Content + public override string? Content { get { return base.Content; } set diff --git a/src/Umbraco.Core/Models/UmbracoDomain.cs b/src/Umbraco.Core/Models/UmbracoDomain.cs index 6930499783..3f2eb00f51 100644 --- a/src/Umbraco.Core/Models/UmbracoDomain.cs +++ b/src/Umbraco.Core/Models/UmbracoDomain.cs @@ -34,7 +34,7 @@ namespace Umbraco.Cms.Core.Models public string DomainName { get => _domainName; - set => SetPropertyValueAndDetectChanges(value, ref _domainName, nameof(DomainName)); + set => SetPropertyValueAndDetectChanges(value, ref _domainName!, nameof(DomainName)); } [DataMember] @@ -49,6 +49,6 @@ namespace Umbraco.Cms.Core.Models /// /// Readonly value of the language ISO code for the domain /// - public string LanguageIsoCode { get; set; } + public string? LanguageIsoCode { get; set; } } } diff --git a/src/Umbraco.Core/Models/UmbracoUserExtensions.cs b/src/Umbraco.Core/Models/UmbracoUserExtensions.cs index 8c4a0cf59b..71612f3531 100644 --- a/src/Umbraco.Core/Models/UmbracoUserExtensions.cs +++ b/src/Umbraco.Core/Models/UmbracoUserExtensions.cs @@ -58,11 +58,11 @@ namespace Umbraco.Extensions return GetUserCulture(user.Language, textService, globalSettings); } - public static CultureInfo GetUserCulture(string userLanguage, ILocalizedTextService textService, GlobalSettings globalSettings) + public static CultureInfo GetUserCulture(string? userLanguage, ILocalizedTextService textService, GlobalSettings globalSettings) { try { - var culture = CultureInfo.GetCultureInfo(userLanguage.Replace("_", "-")); + var culture = CultureInfo.GetCultureInfo(userLanguage!.Replace("_", "-")); // TODO: This is a hack because we store the user language as 2 chars instead of the full culture // which is actually stored in the language files (which are also named with 2 chars!) so we need to attempt // to convert to a supported full culture diff --git a/src/Umbraco.Core/Models/UpgradeCheckResponse.cs b/src/Umbraco.Core/Models/UpgradeCheckResponse.cs index 8ac335e6e7..3238720541 100644 --- a/src/Umbraco.Core/Models/UpgradeCheckResponse.cs +++ b/src/Umbraco.Core/Models/UpgradeCheckResponse.cs @@ -8,20 +8,20 @@ namespace Umbraco.Cms.Core.Models public class UpgradeCheckResponse { [DataMember(Name = "type")] - public string Type { get; set; } + public string? Type { get; set; } [DataMember(Name = "comment")] - public string Comment { get; set; } + public string? Comment { get; set; } [DataMember(Name = "url")] - public string Url { get; set; } + public string? Url { get; set; } public UpgradeCheckResponse() { } public UpgradeCheckResponse(string upgradeType, string upgradeComment, string upgradeUrl, IUmbracoVersion umbracoVersion) { Type = upgradeType; Comment = upgradeComment; - Url = upgradeUrl + "?version=" + WebUtility.UrlEncode(umbracoVersion.Version.ToString(3)); + Url = upgradeUrl + "?version=" + WebUtility.UrlEncode(umbracoVersion.Version?.ToString(3)); } } } diff --git a/src/Umbraco.Core/Models/UserExtensions.cs b/src/Umbraco.Core/Models/UserExtensions.cs index b28033ed5c..ba63780975 100644 --- a/src/Umbraco.Core/Models/UserExtensions.cs +++ b/src/Umbraco.Core/Models/UserExtensions.cs @@ -116,7 +116,7 @@ namespace Umbraco.Cms.Core.Models return ContentPermissions.HasPathAccess(content.Path, user.CalculateContentStartNodeIds(entityService, appCaches), Constants.System.RecycleBinContent); } - public static bool HasPathAccess(this IUser user, IMedia media, IEntityService entityService, AppCaches appCaches) + public static bool HasPathAccess(this IUser user, IMedia? media, IEntityService entityService, AppCaches appCaches) { if (media == null) throw new ArgumentNullException(nameof(media)); return ContentPermissions.HasPathAccess(media.Path, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia); @@ -153,10 +153,17 @@ namespace Umbraco.Cms.Core.Models var runtimeCache = appCaches.IsolatedCaches.GetOrCreate(); var result = runtimeCache.GetCacheItem(cacheKey, () => { - var gsn = user.Groups.Select(x => x.StartContentId).Distinct().ToArray(); + // This returns a nullable array even though we're checking if items have value and there cannot be null + // We use Cast to recast into non-nullable array + var gsn = user.Groups.Where(x => x.StartContentId is not null).Select(x => x.StartContentId).Distinct().Cast().ToArray(); var usn = user.StartContentIds; - var vals = CombineStartNodes(UmbracoObjectTypes.Document, gsn, usn, entityService); - return vals; + if (usn is not null) + { + var vals = CombineStartNodes(UmbracoObjectTypes.Document, gsn, usn, entityService); + return vals; + } + + return null; }, TimeSpan.FromMinutes(2), true); return result; @@ -175,10 +182,15 @@ namespace Umbraco.Cms.Core.Models var runtimeCache = appCaches.IsolatedCaches.GetOrCreate(); var result = runtimeCache.GetCacheItem(cacheKey, () => { - var gsn = user.Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value).Distinct().ToArray(); + var gsn = user.Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId!.Value).Distinct().ToArray(); var usn = user.StartMediaIds; - var vals = CombineStartNodes(UmbracoObjectTypes.Media, gsn, usn, entityService); - return vals; + if (usn is not null) + { + var vals = CombineStartNodes(UmbracoObjectTypes.Media, gsn, usn, entityService); + return vals; + } + + return null; }, TimeSpan.FromMinutes(2), true); return result; diff --git a/src/Umbraco.Core/NamedUdiRange.cs b/src/Umbraco.Core/NamedUdiRange.cs index b66cdb0998..5855f27926 100644 --- a/src/Umbraco.Core/NamedUdiRange.cs +++ b/src/Umbraco.Core/NamedUdiRange.cs @@ -29,6 +29,6 @@ /// /// Gets or sets the name of the range. /// - public string Name { get; set; } + public string? Name { get; set; } } } diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs index dc1126a3c3..2c071ed98c 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs @@ -30,6 +30,7 @@ namespace Umbraco.Cms.Core.PropertyEditors protected ConfigurationEditor(List fields) { Fields = fields; + _defaultConfiguration = new Dictionary(); } /// @@ -49,7 +50,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Gets the configuration as a typed object. /// - public static TConfiguration ConfigurationAs(object obj) + public static TConfiguration? ConfigurationAs(object? obj) { if (obj == null) return default; if (obj is TConfiguration configuration) return configuration; @@ -60,7 +61,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Converts a configuration object into a serialized database value. /// - public static string ToDatabase(object configuration, IConfigurationEditorJsonSerializer configurationEditorJsonSerializer) + public static string? ToDatabase(object configuration, IConfigurationEditorJsonSerializer configurationEditorJsonSerializer) => configuration == null ? null : configurationEditorJsonSerializer.Serialize(configuration); /// @@ -72,14 +73,14 @@ namespace Umbraco.Cms.Core.PropertyEditors } /// - public virtual object DefaultConfigurationObject => DefaultConfiguration; + public virtual object? DefaultConfigurationObject => DefaultConfiguration; /// public virtual bool IsConfiguration(object obj) => obj is IDictionary; /// - public virtual object FromDatabase(string configurationJson, IConfigurationEditorJsonSerializer configurationEditorJsonSerializer) + public virtual object FromDatabase(string? configurationJson, IConfigurationEditorJsonSerializer configurationEditorJsonSerializer) => string.IsNullOrWhiteSpace(configurationJson) ? new Dictionary() : configurationEditorJsonSerializer.Deserialize>(configurationJson); @@ -101,7 +102,7 @@ namespace Umbraco.Cms.Core.PropertyEditors } /// - public virtual IDictionary ToConfigurationEditor(object configuration) + public virtual IDictionary ToConfigurationEditor(object? configuration) { // editors that do not override ToEditor/FromEditor have their configuration // as a dictionary of and, by default, we merge their default @@ -123,7 +124,7 @@ namespace Umbraco.Cms.Core.PropertyEditors } /// - public virtual IDictionary ToValueEditor(object configuration) + public virtual IDictionary? ToValueEditor(object? configuration) => ToConfigurationEditor(configuration); } diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs index 8b7abfafe6..5f860445a0 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.PropertyEditors [DataContract] public class ConfigurationField { - private string _view; + private string? _view; /// /// Initializes a new instance of the class. @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.PropertyEditors // fill details from attribute, if any var attribute = GetType().GetCustomAttribute(false); - if (attribute == null) return; + if (attribute is null) return; Name = attribute.Name; Description = attribute.Description; @@ -51,29 +51,29 @@ namespace Umbraco.Cms.Core.PropertyEditors /// Gets or sets the key of the field. /// [DataMember(Name = "key", IsRequired = true)] - public string Key { get; set; } + public string? Key { get; set; } /// /// Gets or sets the name of the field. /// [DataMember(Name = "label", IsRequired = true)] - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the property name of the field. /// - public string PropertyName { get; set; } + public string? PropertyName { get; set; } /// /// Gets or sets the property CLR type of the field. /// - public Type PropertyType { get; set; } + public Type? PropertyType { get; set; } /// /// Gets or sets the description of the field. /// [DataMember(Name = "description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Gets or sets a value indicating whether to hide the label of the field. @@ -89,7 +89,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// or a simple view name which will map to ~/Views/PreValueEditors/{view}.html. /// [DataMember(Name = "view", IsRequired = true)] - public string View { get; set; } + public string? View { get; set; } /// /// Gets the validators of the field. diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs index ff32308f36..012003db8a 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs @@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.PropertyEditors [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)] public class ConfigurationFieldAttribute : Attribute { - private Type _type; + private Type? _type; /// /// Initializes a new instance of the class. @@ -62,22 +62,22 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// When null or empty, the should derive a key /// from the name of the property marked with this attribute. - public string Key { get; } + public string? Key { get; } /// /// Gets the friendly name of the field. /// - public string Name { get; } + public string? Name { get; } /// /// Gets or sets the view to use to render the field editor. /// - public string View { get; } + public string? View { get; } /// /// Gets or sets the description of the field. /// - public string Description { get; set; } + public string? Description { get; set; } /// /// Gets or sets a value indicating whether the field editor should be displayed without its label. @@ -101,7 +101,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// unless specified otherwise through this property. /// The specified type must inherit from . /// - public Type Type + public Type? Type { get => _type; set diff --git a/src/Umbraco.Core/PropertyEditors/DataEditor.cs b/src/Umbraco.Core/PropertyEditors/DataEditor.cs index e2fc0071be..d235ce7ca7 100644 --- a/src/Umbraco.Core/PropertyEditors/DataEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataEditor.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core.PropertyEditors [DataContract] public class DataEditor : IDataEditor { - private IDictionary _defaultConfiguration; + private IDictionary? _defaultConfiguration; /// /// Initializes a new instance of the class. @@ -36,7 +36,11 @@ namespace Umbraco.Cms.Core.PropertyEditors // assign properties based on the attribute, if it is found Attribute = GetType().GetCustomAttribute(false); - if (Attribute == null) return; + if (Attribute == null) + { + Alias = string.Empty; + return; + } Alias = Attribute.Alias; Type = Attribute.Type; @@ -49,7 +53,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Gets the editor attribute. /// - protected DataEditorAttribute Attribute { get; } + protected DataEditorAttribute? Attribute { get; } /// [DataMember(Name = "alias", IsRequired = true)] @@ -63,7 +67,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// [DataMember(Name = "name", IsRequired = true)] - public string Name { get; internal set; } + public string? Name { get; internal set; } /// [DataMember(Name = "icon")] @@ -103,7 +107,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// Technically, it could be cached by datatype but let's keep things /// simple enough for now. /// - public virtual IDataValueEditor GetValueEditor(object configuration) + public virtual IDataValueEditor GetValueEditor(object? configuration) { // if an explicit value editor has been set (by the manifest parser) // then return it, and ignore the configuration, which is going to be @@ -112,7 +116,11 @@ namespace Umbraco.Cms.Core.PropertyEditors return ExplicitValueEditor; var editor = CreateValueEditor(); - ((DataValueEditor)editor).Configuration = configuration; // TODO: casting is bad + if (configuration is not null) + { + ((DataValueEditor)editor).Configuration = configuration; // TODO: casting is bad + } + return editor; } @@ -121,7 +129,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Used for manifest data editors. [DataMember(Name = "editor")] - public IDataValueEditor ExplicitValueEditor { get; set; } + public IDataValueEditor? ExplicitValueEditor { get; set; } /// /// @@ -139,7 +147,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Used for manifest data editors. [DataMember(Name = "config")] - public IConfigurationEditor ExplicitConfigurationEditor { get; set; } + public IConfigurationEditor? ExplicitConfigurationEditor { get; set; } /// [DataMember(Name = "defaultConfig")] @@ -174,7 +182,7 @@ namespace Umbraco.Cms.Core.PropertyEditors { var editor = new ConfigurationEditor(); // pass the default configuration if this is not a property value editor - if ((Type & EditorType.PropertyValue) == 0) + if ((Type & EditorType.PropertyValue) == 0 && _defaultConfiguration is not null) { editor.DefaultConfiguration = _defaultConfiguration; } diff --git a/src/Umbraco.Core/PropertyEditors/DataEditorAttribute.cs b/src/Umbraco.Core/PropertyEditors/DataEditorAttribute.cs index 639dad1c23..d99acb4781 100644 --- a/src/Umbraco.Core/PropertyEditors/DataEditorAttribute.cs +++ b/src/Umbraco.Core/PropertyEditors/DataEditorAttribute.cs @@ -90,7 +90,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Gets the view to use to render the editor. /// - public string View { get; } + public string? View { get; } /// /// Gets or sets the type of the edited value. diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index 1aa8fce692..28df816acf 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -75,7 +75,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Gets or sets the value editor configuration. /// - public virtual object Configuration { get; set; } + public virtual object? Configuration { get; set; } /// /// Gets or sets the editor view. @@ -86,7 +86,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// [Required] [DataMember(Name = "view")] - public string View { get; set; } + public string? View { get; set; } /// /// The value type which reflects how it is validated and stored in the database @@ -97,7 +97,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// public IEnumerable Validate(object value, bool required, string format) { - List results = null; + List? results = null; var r = Validators.SelectMany(v => v.Validate(value, ValueType, Configuration)).ToList(); if (r.Any()) { results = r; } @@ -153,7 +153,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// /// - internal Attempt TryConvertValueToCrlType(object value) + internal Attempt TryConvertValueToCrlType(object? value) { // if (value is JValue) // value = value.ToString(); @@ -182,7 +182,7 @@ namespace Umbraco.Cms.Core.PropertyEditors //when we compare the values for dirty tracking we'll be comparing an int -> long and they will not match. var result = value.TryConvertTo(valueType); return result.Success && result.Result != null - ? Attempt.Succeed((int)(long)result.Result) + ? Attempt.Succeed((int)(long)result.Result) : result; case ValueStorageType.Decimal: @@ -218,10 +218,10 @@ 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) { //if it's json but it's empty json, then return null - if (ValueType.InvariantEquals(ValueTypes.Json) && editorValue.Value != null && editorValue.Value.ToString().DetectIsEmptyJson()) + if (ValueType.InvariantEquals(ValueTypes.Json) && editorValue.Value != null && (editorValue.Value.ToString()?.DetectIsEmptyJson() ?? true)) { return null; } @@ -247,7 +247,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// The object returned will automatically be serialized into json notation. For most property editors /// the value returned is probably just a string but in some cases a json structure will be returned. /// - public virtual object ToEditor(IProperty property, string? culture = null, string? segment = null) + public virtual object? ToEditor(IProperty property, string? culture = null, string? segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; @@ -259,7 +259,7 @@ namespace Umbraco.Cms.Core.PropertyEditors //if it is a string type, we will attempt to see if it is json stored data, if it is we'll try to convert //to a real json object so we can pass the true json object directly to angular! var asString = val.ToString(); - if (asString.DetectIsJson()) + if (asString?.DetectIsJson() ?? false) { try { @@ -333,7 +333,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// Returns an XText or XCData instance which must be wrapped in a element. /// If the value is empty we will not return as CDATA since that will just take up more space in the file. /// - public XNode ConvertDbToXml(IPropertyType propertyType, object value) + public XNode ConvertDbToXml(IPropertyType propertyType, object? value) { //check for null or empty value, we don't want to return CDATA if that is the case if (value == null || value.ToString().IsNullOrWhiteSpace()) @@ -359,7 +359,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Converts a property value to a string. /// - public virtual string ConvertDbToString(IPropertyType propertyType, object value) + public virtual string ConvertDbToString(IPropertyType propertyType, object? value) { if (value == null) return string.Empty; diff --git a/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs b/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs index a83f925dd3..099fa9126f 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.PropertyEditors { var val = propertyVal.EditedValue; - var valueEditor = editor.GetValueEditor(); + var valueEditor = editor?.GetValueEditor(); if (valueEditor is IDataValueReference reference) { var refs = reference.GetReferences(val); diff --git a/src/Umbraco.Core/PropertyEditors/DateValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DateValueEditor.cs index 308a452d9e..1e65429b6e 100644 --- a/src/Umbraco.Core/PropertyEditors/DateValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DateValueEditor.cs @@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.PropertyEditors Validators.Add(new DateTimeValidator()); } - public override object ToEditor(IProperty property, string culture= null, string? segment = null) + public override object ToEditor(IProperty property, string? culture= null, string? segment = null) { var date = property.GetValue(culture, segment).TryConvertTo(); if (date.Success == false || date.Result == null) diff --git a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs index b70a1be851..78061a1be4 100644 --- a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs @@ -10,9 +10,9 @@ 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>( + yield return new KeyValuePair>( property.Alias, property.GetValue(culture, segment, published).Yield()); } diff --git a/src/Umbraco.Core/PropertyEditors/GridEditor.cs b/src/Umbraco.Core/PropertyEditors/GridEditor.cs index 06f32658d2..0e7b238900 100644 --- a/src/Umbraco.Core/PropertyEditors/GridEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/GridEditor.cs @@ -11,25 +11,26 @@ namespace Umbraco.Cms.Core.PropertyEditors public GridEditor() { Config = new Dictionary(); + Alias = string.Empty; } [DataMember(Name = "name", IsRequired = true)] - public string Name { get; set; } + public string? Name { get; set; } [DataMember(Name = "nameTemplate")] - public string NameTemplate { get; set; } + public string? NameTemplate { get; set; } [DataMember(Name = "alias", IsRequired = true)] public string Alias { get; set; } [DataMember(Name = "view", IsRequired = true)] - public string View{ get; set; } + public string? View{ get; set; } [DataMember(Name = "render")] - public string Render { get; set; } + public string? Render { get; set; } [DataMember(Name = "icon", IsRequired = true)] - public string Icon { get; set; } + public string? Icon { get; set; } [DataMember(Name = "config")] public IDictionary Config { get; set; } @@ -46,7 +47,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// true if the specified object is equal to the current object; otherwise, false. /// /// The object to compare with the current object. - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs b/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs index b1acfc3e44..2d5653f394 100644 --- a/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// dictionary of key/values. For advanced editors which inherit from , /// this will be an actual configuration object (ie an instance of TConfiguration. /// - object DefaultConfigurationObject { get; } + object? DefaultConfigurationObject { get; } /// /// Determines whether a configuration object is of the type expected by the configuration editor. @@ -71,6 +71,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// Converts the configuration object to values for the value editor. /// /// The configuration. - IDictionary ToValueEditor(object? configuration); + IDictionary? ToValueEditor(object? configuration); } } diff --git a/src/Umbraco.Core/PropertyEditors/IDataEditor.cs b/src/Umbraco.Core/PropertyEditors/IDataEditor.cs index 403bf4ffeb..038aced3f3 100644 --- a/src/Umbraco.Core/PropertyEditors/IDataEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/IDataEditor.cs @@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Gets the name of the editor. /// - string Name { get; } + string? Name { get; } /// /// Gets the icon of the editor. @@ -57,7 +57,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// Gets the configuration for the value editor. /// - IDictionary DefaultConfiguration { get; } + IDictionary? DefaultConfiguration { get; } /// /// Gets an editor to edit the value editor configuration. diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs index af5ddb1ec8..d44d732464 100644 --- a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs +++ b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs @@ -14,6 +14,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// /// - IEnumerable GetReferences(object value); + IEnumerable GetReferences(object? value); } } diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueReferenceFactory.cs b/src/Umbraco.Core/PropertyEditors/IDataValueReferenceFactory.cs index 6acfccf4e7..fd1f2f50d2 100644 --- a/src/Umbraco.Core/PropertyEditors/IDataValueReferenceFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/IDataValueReferenceFactory.cs @@ -7,7 +7,7 @@ /// /// /// A value indicating whether the converter supports a datatype. - bool IsForEditor(IDataEditor dataEditor); + bool IsForEditor(IDataEditor? dataEditor); /// /// diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs index d3a8a2bac5..20db0a49a1 100644 --- a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs @@ -19,6 +19,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// values. By default, there would be only one object: the property value. But some implementations may return /// more than one value for a given field. /// - IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published); + IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published); } } diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs b/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs index 392a133b11..499a691204 100644 --- a/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs @@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// could contain JSON, the decision could be made on the intermediate value. Or, if it is /// a picker, it could be made on the object value (the actual picked object). /// - bool? IsValue(object value, PropertyValueLevel level); + bool? IsValue(object? value, PropertyValueLevel level); /// /// Gets the type of values returned by the converter. @@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// strings, and xml-whitespace strings appropriately, ie it should know whether to preserve /// white spaces. /// - object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview); + object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview); /// /// Converts a property intermediate value to an Object value. @@ -83,7 +83,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// passed to eg a PublishedFragment constructor. It is used by the fragment and the properties to manage /// the cache levels of property values. It is not meant to be used by the converter. /// - object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview); + object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview); /// /// Converts a property intermediate value to an XPath value. @@ -107,6 +107,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// passed to eg a PublishedFragment constructor. It is used by the fragment and the properties to manage /// the cache levels of property values. It is not meant to be used by the converter. /// - object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview); + object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview); } } diff --git a/src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs b/src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs index 8c59d3492c..9674eaea98 100644 --- a/src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs @@ -19,6 +19,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// The is expected to be a valid regular expression. /// This is used to validate values against the property type validation regular expression. /// - IEnumerable ValidateFormat(object value, string valueType, string format); + IEnumerable ValidateFormat(object? value, string valueType, string format); } } diff --git a/src/Umbraco.Core/PropertyEditors/IValueValidator.cs b/src/Umbraco.Core/PropertyEditors/IValueValidator.cs index 0c97f0a41b..f4c45fdd3d 100644 --- a/src/Umbraco.Core/PropertyEditors/IValueValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/IValueValidator.cs @@ -18,6 +18,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// The value can be a string, a Json structure (JObject, JArray...)... corresponding to what was posted by an editor. /// - IEnumerable Validate(object value, string valueType, object dataTypeConfiguration); + IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration); } } diff --git a/src/Umbraco.Core/PropertyEditors/ListViewConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ListViewConfiguration.cs index a09f42b62e..055867e80b 100644 --- a/src/Umbraco.Core/PropertyEditors/ListViewConfiguration.cs +++ b/src/Umbraco.Core/PropertyEditors/ListViewConfiguration.cs @@ -60,10 +60,10 @@ namespace Umbraco.Cms.Core.PropertyEditors public BulkActionPermissionSettings BulkActionPermissions { get; set; } = new BulkActionPermissionSettings(); // TODO: managing defaults? [ConfigurationField("icon", "Content app icon", "views/propertyeditors/listview/icon.prevalues.html", Description = "The icon of the listview content app")] - public string Icon { get; set; } + public string? Icon { get; set; } [ConfigurationField("tabName", "Content app name", "textstring", Description = "The name of the listview content app (default if empty: 'Child Items')")] - public string TabName { get; set; } + public string? TabName { get; set; } [ConfigurationField("showContentFirst", "Show Content App First", "boolean", Description = "Enable this to show the content app by default instead of the list view app")] public bool ShowContentFirst { get; set; } @@ -75,13 +75,13 @@ namespace Umbraco.Cms.Core.PropertyEditors public class Property { [DataMember(Name = "alias")] - public string Alias { get; set; } + public string? Alias { get; set; } [DataMember(Name = "header")] - public string Header { get; set; } + public string? Header { get; set; } [DataMember(Name = "nameTemplate")] - public string Template { get; set; } + public string? Template { get; set; } [DataMember(Name = "isSystem")] public int IsSystem { get; set; } // TODO: bool @@ -91,13 +91,13 @@ namespace Umbraco.Cms.Core.PropertyEditors public class Layout { [DataMember(Name = "name")] - public string Name { get; set; } + public string? Name { get; set; } [DataMember(Name = "path")] - public string Path { get; set; } + public string? Path { get; set; } [DataMember(Name = "icon")] - public string Icon { get; set; } + public string? Icon { get; set; } [DataMember(Name = "isSystem")] public int IsSystem { get; set; } // TODO: bool diff --git a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs b/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs index 9e26362bc2..81b1c1fba1 100644 --- a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs @@ -12,13 +12,13 @@ namespace Umbraco.Cms.Core.PropertyEditors { } - public IManifestValueValidator Create(string name) + public IManifestValueValidator? Create(string name) { var v = GetByName(name); // TODO: what is this exactly? // we cannot return this instance, need to clone it? - return (IManifestValueValidator) Activator.CreateInstance(v.GetType()); // ouch + return (IManifestValueValidator?) Activator.CreateInstance(v.GetType()); // ouch } public IManifestValueValidator GetByName(string name) diff --git a/src/Umbraco.Core/PropertyEditors/MediaUrlGeneratorCollection.cs b/src/Umbraco.Core/PropertyEditors/MediaUrlGeneratorCollection.cs index 380017c5a2..a58203c7b5 100644 --- a/src/Umbraco.Core/PropertyEditors/MediaUrlGeneratorCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/MediaUrlGeneratorCollection.cs @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.PropertyEditors : base(items) { } - public bool TryGetMediaPath(string propertyEditorAlias, object value, out string mediaPath) + public bool TryGetMediaPath(string? propertyEditorAlias, object? value, out string? mediaPath) { // We can't get a media path from a null value // The value will be null when uploading a brand new image, since we try to get the "old path" which doesn't exist yet diff --git a/src/Umbraco.Core/PropertyEditors/MissingPropertyEditor.cs b/src/Umbraco.Core/PropertyEditors/MissingPropertyEditor.cs index 0bffd5fce3..ba1d03e7bb 100644 --- a/src/Umbraco.Core/PropertyEditors/MissingPropertyEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/MissingPropertyEditor.cs @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core.PropertyEditors throw new NotImplementedException(); } - public IDataValueEditor GetValueEditor(object configuration) + public IDataValueEditor GetValueEditor(object? configuration) { throw new NotImplementedException(); } diff --git a/src/Umbraco.Core/PropertyEditors/ParameterEditorCollection.cs b/src/Umbraco.Core/PropertyEditors/ParameterEditorCollection.cs index 39647bb753..c58c962df4 100644 --- a/src/Umbraco.Core/PropertyEditors/ParameterEditorCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/ParameterEditorCollection.cs @@ -13,10 +13,10 @@ namespace Umbraco.Cms.Core.PropertyEditors { } // note: virtual so it can be mocked - public virtual IDataEditor this[string alias] + public virtual IDataEditor? this[string alias] => this.SingleOrDefault(x => x.Alias == alias); - public virtual bool TryGet(string alias, out IDataEditor editor) + public virtual bool TryGet(string alias, out IDataEditor? editor) { editor = this.FirstOrDefault(x => x.Alias == alias); return editor != null; diff --git a/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs b/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs index 3d6c0adff6..ac275c46e3 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyCacheCompression.cs @@ -44,7 +44,7 @@ namespace Umbraco.Cms.Core.PropertyEditors if (!_propertyEditors.TryGet(propertyType.PropertyEditorAlias, out var propertyEditor)) return false; - return _compressionOptions.IsCompressed(content, propertyType, propertyEditor, published); + return _compressionOptions.IsCompressed(content, propertyType, propertyEditor!, published); }); return compressedStorage; diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditorCollection.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditorCollection.cs index 1ddf150f93..1ce7742eb6 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyEditorCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditorCollection.cs @@ -18,10 +18,10 @@ namespace Umbraco.Cms.Core.PropertyEditors { } // note: virtual so it can be mocked - public virtual IDataEditor this[string alias] + public virtual IDataEditor? this[string? alias] => this.SingleOrDefault(x => x.Alias == alias); - public virtual bool TryGet(string alias, out IDataEditor editor) + public virtual bool TryGet(string alias, out IDataEditor? editor) { editor = this.FirstOrDefault(x => x.Alias == alias); return editor != null; diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditorTagsExtensions.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditorTagsExtensions.cs index ddd12c5003..fa57956cdd 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyEditorTagsExtensions.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditorTagsExtensions.cs @@ -16,7 +16,7 @@ namespace Umbraco.Extensions /// /// Gets the tags configuration attribute of an editor. /// - public static TagsPropertyEditorAttribute GetTagAttribute(this IDataEditor editor) + public static TagsPropertyEditorAttribute? GetTagAttribute(this IDataEditor? editor) => editor?.GetType().GetCustomAttribute(false); } } diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs index 9da1df938f..0442ae1b18 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs @@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.PropertyEditors => false; /// - public virtual bool? IsValue(object value, PropertyValueLevel level) + public virtual bool? IsValue(object? value, PropertyValueLevel level) { switch (level) { @@ -47,15 +47,15 @@ namespace Umbraco.Cms.Core.PropertyEditors => PropertyCacheLevel.Snapshot; /// - public virtual object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public virtual object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) => source; /// - public virtual object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public virtual object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) => inter; /// - public virtual object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public virtual object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) => inter?.ToString() ?? string.Empty; } } diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueConverterCollection.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueConverterCollection.cs index a60ba4a6e5..9214f10482 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyValueConverterCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyValueConverterCollection.cs @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.PropertyEditors } private readonly object _locker = new object(); - private Dictionary _defaultConverters; + private Dictionary? _defaultConverters; private Dictionary DefaultConverters { @@ -42,6 +42,6 @@ namespace Umbraco.Cms.Core.PropertyEditors => DefaultConverters.ContainsKey(converter); internal bool Shadows(IPropertyValueConverter shadowing, IPropertyValueConverter shadowed) - => DefaultConverters.TryGetValue(shadowing, out Type[] types) && types.Contains(shadowed.GetType()); + => DefaultConverters.TryGetValue(shadowing, out Type[]? types) && types.Contains(shadowed.GetType()); } } diff --git a/src/Umbraco.Core/PropertyEditors/TagsPropertyEditorAttribute.cs b/src/Umbraco.Core/PropertyEditors/TagsPropertyEditorAttribute.cs index 9075d9be97..c21ea09ac9 100644 --- a/src/Umbraco.Core/PropertyEditors/TagsPropertyEditorAttribute.cs +++ b/src/Umbraco.Core/PropertyEditors/TagsPropertyEditorAttribute.cs @@ -56,6 +56,6 @@ namespace Umbraco.Cms.Core.PropertyEditors /// Gets the type of the dynamic configuration provider. /// //TODO: This is not used and should be implemented in a nicer way, see https://github.com/umbraco/Umbraco-CMS/issues/6017#issuecomment-516253562 - public Type TagsConfigurationProviderType { get; } + public Type? TagsConfigurationProviderType { get; } } } diff --git a/src/Umbraco.Core/PropertyEditors/TextOnlyValueEditor.cs b/src/Umbraco.Core/PropertyEditors/TextOnlyValueEditor.cs index 7674b92600..cb401cf92a 100644 --- a/src/Umbraco.Core/PropertyEditors/TextOnlyValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/TextOnlyValueEditor.cs @@ -43,7 +43,7 @@ namespace Umbraco.Cms.Core.PropertyEditors { case ValueStorageType.Ntext: case ValueStorageType.Nvarchar: - return val.ToString(); + return val.ToString() ?? string.Empty; case ValueStorageType.Integer: case ValueStorageType.Decimal: case ValueStorageType.Date: diff --git a/src/Umbraco.Core/PropertyEditors/TextStringValueConverter.cs b/src/Umbraco.Core/PropertyEditors/TextStringValueConverter.cs index 5b9977518b..60f4169ce6 100644 --- a/src/Umbraco.Core/PropertyEditors/TextStringValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/TextStringValueConverter.cs @@ -31,25 +31,25 @@ namespace Umbraco.Cms.Core.PropertyEditors public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Snapshot; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) return null; var sourceString = source.ToString(); // ensures string is parsed for {localLink} and URLs are resolved correctly - sourceString = _linkParser.EnsureInternalLinks(sourceString, preview); + sourceString = _linkParser.EnsureInternalLinks(sourceString!, preview); sourceString = _urlParser.EnsureUrls(sourceString); return sourceString; } - public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { // source should come from ConvertSource and be a string (or null) already return inter ?? string.Empty; } - public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { // source should come from ConvertSource and be a string (or null) already return inter; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/DateTimeValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/DateTimeValidator.cs index 69c004376d..e390c3f493 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/DateTimeValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/DateTimeValidator.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators /// public class DateTimeValidator : IValueValidator { - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { //don't validate if empty if (value == null || value.ToString().IsNullOrWhiteSpace()) diff --git a/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs index 7393603f85..b68f4848aa 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators public string ValidationName => "Decimal"; /// - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { if (value == null || value.ToString() == string.Empty) yield break; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/DelimitedValueValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/DelimitedValueValidator.cs index 749f06d43f..a03251e978 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/DelimitedValueValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/DelimitedValueValidator.cs @@ -16,11 +16,11 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators /// /// Gets or sets the configuration, when parsed as . /// - public DelimitedValueValidatorConfig Configuration { get; set; } + public DelimitedValueValidatorConfig? Configuration { get; set; } /// - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { // TODO: localize these! if (value != null) @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators var regex = (Configuration?.Pattern != null) ? new Regex(Configuration.Pattern) : null; var stringVal = value.ToString(); - var split = stringVal.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); + var split = stringVal!.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); for (var i = 0; i < split.Length; i++) { var s = split[i]; @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators public class DelimitedValueValidatorConfig { - public string Delimiter { get; set; } - public string Pattern { get; set; } + public string? Delimiter { get; set; } + public string? Pattern { get; set; } } } diff --git a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs index 04bf411f6e..90c37d54b4 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators public string ValidationName => "Email"; /// - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { var asString = value == null ? "" : value.ToString(); diff --git a/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs index 7ed9a7b56d..6c8e06ef3d 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators public string ValidationName => "Integer"; /// - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { if (value != null && value.ToString() != string.Empty) { diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs index ea57e66481..c655c02754 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs @@ -30,7 +30,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators /// and the regular expression is supplied at validation time. This constructor is also used when /// the validator is used as an and the regular expression /// is supplied via the method. - public RegexValidator(ILocalizedTextService textService) : this(textService, null) + public RegexValidator(ILocalizedTextService textService) : this(textService, string.Empty) { } /// @@ -60,7 +60,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators } /// - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { if (_regex == null) { @@ -71,11 +71,11 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators } /// - public IEnumerable ValidateFormat(object value, string valueType, string format) + public IEnumerable ValidateFormat(object? value, string valueType, string format) { if (format == null) throw new ArgumentNullException(nameof(format)); if (string.IsNullOrWhiteSpace(format)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(format)); - if (value == null || !new Regex(format).IsMatch(value.ToString())) + if (value == null || !new Regex(format).IsMatch(value.ToString()!)) { yield return new ValidationResult(_textService?.Localize("validation", "invalidPattern") ?? ValueIsInvalid, new[] { "value" }); } diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs index 3a7ec2b934..c1ebf62390 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators public string ValidationName => "Required"; /// - public IEnumerable Validate(object value, string valueType, object dataTypeConfiguration) + public IEnumerable Validate(object value, string valueType, object? dataTypeConfiguration) { return ValidateRequired(value, valueType); } @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators if (valueType.InvariantEquals(ValueTypes.Json)) { - if (value.ToString().DetectIsEmptyJson()) + if (value.ToString()?.DetectIsEmptyJson() ?? false) { yield return new ValidationResult(_textService?.Localize("validation", "invalidEmpty") ?? ValueCannotBeEmpty, new[] { "value" }); diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/CheckboxListValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/CheckboxListValueConverter.cs index c3fa110adb..0e89770956 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/ContentPickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ContentPickerValueConverter.cs index 4a33b6cc47..3392c504e5 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/ContentPickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ContentPickerValueConverter.cs @@ -28,7 +28,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Elements; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) return null; @@ -54,27 +54,27 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return null; } - public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object? ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { if (inter == null) return null; if ((propertyType.Alias != null && PropertiesToExclude.Contains(propertyType.Alias.ToLower(CultureInfo.InvariantCulture))) == false) { - IPublishedContent content; + IPublishedContent? content; var publishedSnapshot = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot(); if (inter is int id) { - content = publishedSnapshot.Content.GetById(id); + content = publishedSnapshot?.Content.GetById(id); if (content != null) return content; } else { var udi = inter as GuidUdi; - if (udi == null) + if (udi is null) return null; - content = publishedSnapshot.Content.GetById(udi.Guid); + content = publishedSnapshot?.Content.GetById(udi.Guid); if (content != null && content.ContentType.ItemType == PublishedItemType.Content) return content; } @@ -83,7 +83,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return inter; } - public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { if (inter == null) return null; return inter.ToString(); diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DatePickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DatePickerValueConverter.cs index 831d574d20..7182719ee1 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DatePickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/DatePickerValueConverter.cs @@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) return DateTime.MinValue; @@ -39,9 +39,13 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters // default ConvertSourceToObject just returns source ie a DateTime value - public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { // source should come from ConvertSource and be a DateTime already + if (inter is null) + { + return null; + } return XmlConvert.ToString((DateTime) inter, XmlDateTimeSerializationMode.Unspecified); } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs index e9ede82590..06eb23bc70 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) { diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs index 668afe65bf..ea7a8b2301 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/EmailAddressValueConverter.cs @@ -16,7 +16,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) { return source?.ToString() ?? string.Empty; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/EyeDropperValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/EyeDropperValueConverter.cs index 69f768ce6d..6ea5aae9bb 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/EyeDropperValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/EyeDropperValueConverter.cs @@ -16,7 +16,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) => source?.ToString() ?? string.Empty; } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/IntegerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/IntegerValueConverter.cs index a27ef9cb49..4bffc5a928 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/IntegerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/IntegerValueConverter.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { return source.TryConvertTo().Result; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/LabelValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/LabelValueConverter.cs index c873b29b98..9f2c06cdf9 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/LabelValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/LabelValueConverter.cs @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override Type GetPropertyValueType(IPublishedPropertyType propertyType) { var valueType = ConfigurationEditor.ConfigurationAs(propertyType.DataType.Configuration); - switch (valueType.ValueType) + switch (valueType?.ValueType) { case ValueTypes.DateTime: case ValueTypes.Date: @@ -43,10 +43,10 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { var valueType = ConfigurationEditor.ConfigurationAs(propertyType.DataType.Configuration); - switch (valueType.ValueType) + switch (valueType?.ValueType) { case ValueTypes.DateTime: case ValueTypes.Date: diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MediaPickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MediaPickerValueConverter.cs index 31f78f58d9..ea244cf5a0 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MediaPickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MediaPickerValueConverter.cs @@ -44,39 +44,39 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters private bool IsMultipleDataType(PublishedDataType dataType) { var config = ConfigurationEditor.ConfigurationAs(dataType.Configuration); - return config.Multiple; + return config?.Multiple ?? false; } - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, - object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, + object? source, bool preview) { if (source == null) return null; - var nodeIds = source.ToString() + var nodeIds = source.ToString()? .Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries) .Select(UdiParser.Parse) .ToArray(); return nodeIds; } - 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 isMultiple = IsMultipleDataType(propertyType.DataType); - var udis = (Udi[])source; + var udis = (Udi[]?)source; var mediaItems = new List(); if (source == null) return isMultiple ? mediaItems : null; - if (udis.Any()) + if (udis?.Any() ?? false) { var publishedSnapshot = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot(); foreach (var udi in udis) { var guidUdi = udi as GuidUdi; - if (guidUdi == null) continue; - var item = publishedSnapshot.Media.GetById(guidUdi.Guid); + if (guidUdi is null) continue; + var item = publishedSnapshot?.Media.GetById(guidUdi.Guid); if (item != null) mediaItems.Add(item); } @@ -87,6 +87,6 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return source; } - private object FirstOrDefault(IList mediaItems) => mediaItems.Count == 0 ? null : mediaItems[0]; + private object? FirstOrDefault(IList mediaItems) => mediaItems.Count == 0 ? null : mediaItems[0]; } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberGroupPickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberGroupPickerValueConverter.cs index 61b8a27f24..2fcaa011fd 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberGroupPickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberGroupPickerValueConverter.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { return source?.ToString() ?? string.Empty; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberPickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberPickerValueConverter.cs index a891021ec4..5d431296f9 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberPickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MemberPickerValueConverter.cs @@ -34,7 +34,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override Type GetPropertyValueType(IPublishedPropertyType propertyType) => typeof(IPublishedContent); - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) return null; @@ -48,14 +48,14 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return null; } - 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) { if (source == null) { return null; } - IPublishedContent member; + IPublishedContent? member; var publishedSnapshot = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot(); if (source is int id) { @@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters { return null; } - member = publishedSnapshot.Members.Get(m); + member = publishedSnapshot?.Members.Get(m); if (member != null) { return member; @@ -73,7 +73,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters else { var sourceUdi = source as GuidUdi; - if (sourceUdi == null) + if (sourceUdi is null) return null; IMember m = _memberService.GetByKey(sourceUdi.Guid); @@ -82,7 +82,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return null; } - member = publishedSnapshot.Members.Get(m); + member = publishedSnapshot?.Members.Get(m); if (member != null) { diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs index e3e94cd95e..4bfb4db713 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs @@ -51,13 +51,13 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters ? typeof(IPublishedContent) : typeof(IEnumerable); - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) return null; if (propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.MultiNodeTreePicker)) { - var nodeIds = source.ToString() + var nodeIds = source.ToString()? .Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries) .Select(UdiParser.Parse) .ToArray(); @@ -66,7 +66,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return null; } - 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) { if (source == null) { @@ -90,16 +90,16 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters foreach (var udi in udis) { var guidUdi = udi as GuidUdi; - if (guidUdi == null) continue; + if (guidUdi is null) continue; - IPublishedContent multiNodeTreePickerItem = null; + IPublishedContent? multiNodeTreePickerItem = null; switch (udi.EntityType) { case Constants.UdiEntityType.Document: - multiNodeTreePickerItem = GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Document, id => publishedSnapshot.Content.GetById(guidUdi.Guid)); + multiNodeTreePickerItem = GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Document, id => publishedSnapshot?.Content.GetById(guidUdi.Guid)); break; case Constants.UdiEntityType.Media: - multiNodeTreePickerItem = GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Media, id => publishedSnapshot.Media.GetById(guidUdi.Guid)); + multiNodeTreePickerItem = GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Media, id => publishedSnapshot?.Media.GetById(guidUdi.Guid)); break; case Constants.UdiEntityType.Member: multiNodeTreePickerItem = GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Member, id => @@ -109,7 +109,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters { return null; } - IPublishedContent member = publishedSnapshot.Members.Get(m); + IPublishedContent? member = publishedSnapshot?.Members.Get(m); return member; }); break; @@ -147,7 +147,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters /// The type of content expected/supported by /// A function to fetch content of type /// The requested content, or null if either it does not exist or does not match - private IPublishedContent GetPublishedContent(T nodeId, ref UmbracoObjectTypes actualType, UmbracoObjectTypes expectedType, Func contentFetcher) + private IPublishedContent? GetPublishedContent(T nodeId, ref UmbracoObjectTypes actualType, UmbracoObjectTypes expectedType, Func contentFetcher) { // is the actual type supported by the content fetcher? if (actualType != UmbracoObjectTypes.Unknown && actualType != expectedType) @@ -166,6 +166,6 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return content; } - private static bool IsSingleNodePicker(IPublishedPropertyType propertyType) => propertyType.DataType.ConfigurationAs().MaxNumber == 1; + private static bool IsSingleNodePicker(IPublishedPropertyType propertyType) => propertyType.DataType.ConfigurationAs()?.MaxNumber == 1; } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs index f7dccbf74d..b4ce51c077 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters private static readonly string[] NewLineDelimiters = { "\r\n", "\r", "\n" }; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { // data is (both in database and xml): // @@ -58,18 +58,21 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters : values.ToArray(); } - public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { var d = new XmlDocument(); var e = d.CreateElement("values"); d.AppendChild(e); - var values = (IEnumerable) inter; - foreach (var value in values) + var values = (IEnumerable?) inter; + if (values is not null) { - var ee = d.CreateElement("value"); - ee.InnerText = value; - e.AppendChild(ee); + foreach (var value in values) + { + var ee = d.CreateElement("value"); + ee.InnerText = value; + e.AppendChild(ee); + } } return d.CreateNavigator(); diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MustBeStringValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MustBeStringValueConverter.cs index afefa4d156..d172e534c4 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MustBeStringValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MustBeStringValueConverter.cs @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { return source?.ToString(); } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/RadioButtonListValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/RadioButtonListValueConverter.cs index f2b41dd139..162764fbf5 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/RadioButtonListValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/RadioButtonListValueConverter.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { var attempt = source.TryConvertTo(); diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/SimpleTinyMceValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/SimpleTinyMceValueConverter.cs index db5376f52a..1ad867bfd0 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/SimpleTinyMceValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/SimpleTinyMceValueConverter.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { // in xml a string is: string // in the database a string is: string @@ -28,13 +28,13 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return source; } - public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { // source should come from ConvertSource and be a string (or null) already return new HtmlEncodedString(inter == null ? string.Empty : (string)inter); } - public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object? ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { // source should come from ConvertSource and be a string (or null) already return inter; diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs index 67671ee662..c0293a0241 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/SliderValueConverter.cs @@ -26,18 +26,18 @@ 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) { if (source == null) return null; if (IsRangeDataType(propertyType.DataType.Id)) { - var rangeRawValues = source.ToString().Split(Constants.CharArrays.Comma); + var rangeRawValues = source.ToString()!.Split(Constants.CharArrays.Comma); var minimumAttempt = rangeRawValues[0].TryConvertTo(); var maximumAttempt = rangeRawValues[1].TryConvertTo(); - if (minimumAttempt.Success && maximumAttempt.Success) + if ((minimumAttempt.Success) && (maximumAttempt.Success)) { return new Range { Maximum = maximumAttempt.Result, Minimum = minimumAttempt.Result }; } @@ -72,7 +72,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters { var dataType = _dataTypeService.GetDataType(id); var configuration = dataType.ConfigurationAs(); - return configuration.EnableRange; + return configuration?.EnableRange ?? false; }); } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs index 7b14f5caf7..2c45e5090a 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs @@ -30,24 +30,24 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object? ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { if (source == null) return Array.Empty(); // if Json storage type deserialize and return as string array if (JsonStorageType(propertyType.DataType.Id)) { - var array = _jsonSerializer.Deserialize(source.ToString()); + var array = source.ToString() is not null ? _jsonSerializer.Deserialize(source.ToString()!) : null; return array ?? Array.Empty(); } // Otherwise assume CSV storage type and return as string array - return source.ToString().Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries); + return source.ToString()?.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries); } - 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) { - return (string[]) source; + return (string[]?) source; } /// @@ -68,7 +68,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters return Storages.GetOrAdd(dataTypeId, id => { var configuration = _dataTypeService.GetDataType(id).ConfigurationAs(); - return configuration.StorageType == TagsStorageType.Json; + return configuration?.StorageType == TagsStorageType.Json; }); } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/UploadPropertyConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/UploadPropertyConverter.cs index 0dc33c25b6..a554e7d134 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/UploadPropertyConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/UploadPropertyConverter.cs @@ -18,7 +18,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) { return source?.ToString() ?? ""; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/YesNoValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/YesNoValueConverter.cs index 455ea5417d..6534ce3f14 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/YesNoValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/YesNoValueConverter.cs @@ -15,7 +15,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element; - public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview) + public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object? source, bool preview) { // in xml a boolean is: string // in the database a boolean is: string "1" or "0" or empty @@ -49,10 +49,10 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters // default ConvertSourceToObject just returns source ie a boolean value - public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) + public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview) { // source should come from ConvertSource and be a boolean already - return (bool)inter ? "1" : "0"; + return (bool?)inter ?? false ? "1" : "0"; } } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueTypes.cs b/src/Umbraco.Core/PropertyEditors/ValueTypes.cs index 28e8fbf58e..3a99a70a14 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueTypes.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueTypes.cs @@ -16,11 +16,11 @@ namespace Umbraco.Cms.Core.PropertyEditors public static class ValueTypes { // the auto, static, set of valid values - private static readonly HashSet Values - = new HashSet(typeof(ValueTypes) + private static readonly HashSet Values + = new HashSet(typeof(ValueTypes) .GetFields(BindingFlags.Static | BindingFlags.Public) .Where(x => x.IsLiteral && !x.IsInitOnly) - .Select(x => (string) x.GetRawConstantValue())); + .Select(x => (string?) x.GetRawConstantValue())); /// /// Date value. diff --git a/src/Umbraco.Core/PropertyEditors/VoidEditor.cs b/src/Umbraco.Core/PropertyEditors/VoidEditor.cs index 8510c982ab..28a0afb6ce 100644 --- a/src/Umbraco.Core/PropertyEditors/VoidEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/VoidEditor.cs @@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// The default alias of the editor is "Umbraco.Void". When a suffix is provided, /// it is appended to the alias. Eg if the suffix is "Foo" the alias is "Umbraco.Void.Foo". public VoidEditor( - string aliasSuffix, + string? aliasSuffix, IDataValueEditorFactory dataValueEditorFactory) : base(dataValueEditorFactory) { diff --git a/src/Umbraco.Core/PublishedCache/IPublishedCache.cs b/src/Umbraco.Core/PublishedCache/IPublishedCache.cs index 757d51cb65..bdc95c9563 100644 --- a/src/Umbraco.Core/PublishedCache/IPublishedCache.cs +++ b/src/Umbraco.Core/PublishedCache/IPublishedCache.cs @@ -94,7 +94,7 @@ namespace Umbraco.Cms.Core.PublishedCache /// A culture. /// The contents. /// Considers published or unpublished content depending on defaults. - IEnumerable GetAtRoot(string culture = null); + IEnumerable GetAtRoot(string? culture = null); /// /// Gets a content resulting from an XPath query. diff --git a/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs b/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs index bff2a3b838..714de258e0 100644 --- a/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs +++ b/src/Umbraco.Core/PublishedCache/IPublishedSnapshot.cs @@ -56,6 +56,6 @@ namespace Umbraco.Cms.Core.PublishedCache /// Forcing to false means no preview. Forcing to true means 'full' preview if the snapshot is not already previewing; /// otherwise the snapshot keeps previewing according to whatever settings it is using already. /// Stops forcing preview when disposed. - IDisposable ForcedPreview(bool preview, Action callback = null); + IDisposable ForcedPreview(bool preview, Action? callback = null); } } diff --git a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs index 1fe2c9636b..3a4b5a24b0 100644 --- a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs +++ b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotAccessor.cs @@ -5,6 +5,6 @@ namespace Umbraco.Cms.Core.PublishedCache /// public interface IPublishedSnapshotAccessor { - bool TryGetPublishedSnapshot(out IPublishedSnapshot publishedSnapshot); + bool TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot); } } diff --git a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs index 360f277da3..f4416f85ac 100644 --- a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs +++ b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs @@ -46,9 +46,9 @@ namespace Umbraco.Cms.Core.PublishedCache /// RefreshAllPublishedSnapshot method. /// void Rebuild( - IReadOnlyCollection contentTypeIds = null, - IReadOnlyCollection mediaTypeIds = null, - IReadOnlyCollection memberTypeIds = null); + IReadOnlyCollection? contentTypeIds = null, + IReadOnlyCollection? mediaTypeIds = null, + IReadOnlyCollection? memberTypeIds = null); /* An IPublishedCachesService implementation can rely on transaction-level events to update * its internal, database-level data, as these events are purely internal. However, it cannot diff --git a/src/Umbraco.Core/PublishedCache/ITagQuery.cs b/src/Umbraco.Core/PublishedCache/ITagQuery.cs index 870abd5d6d..186ab7f919 100644 --- a/src/Umbraco.Core/PublishedCache/ITagQuery.cs +++ b/src/Umbraco.Core/PublishedCache/ITagQuery.cs @@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.PublishedCache /// /// Gets all documents tagged with the specified tag. /// - IEnumerable GetContentByTag(string tag, string group = null, string? culture = null); + IEnumerable GetContentByTag(string tag, string? group = null, string? culture = null); /// /// Gets all documents tagged with any tag in the specified group. @@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.PublishedCache /// /// Gets all media tagged with the specified tag. /// - IEnumerable GetMediaByTag(string tag, string group = null, string? culture = null); + IEnumerable GetMediaByTag(string tag, string? group = null, string? culture = null); /// /// Gets all media tagged with any tag in the specified group. @@ -29,31 +29,31 @@ namespace Umbraco.Cms.Core.PublishedCache /// /// Gets all tags. /// - IEnumerable GetAllTags(string group = null, string? culture = null); + IEnumerable GetAllTags(string? group = null, string? culture = null); /// /// Gets all document tags. /// - IEnumerable GetAllContentTags(string group = null, string? culture = null); + IEnumerable GetAllContentTags(string? group = null, string? culture = null); /// /// Gets all media tags. /// - IEnumerable GetAllMediaTags(string group = null, string? culture = null); + IEnumerable GetAllMediaTags(string? group = null, string? culture = null); /// /// Gets all member tags. /// - IEnumerable GetAllMemberTags(string group = null, string? culture = null); + IEnumerable GetAllMemberTags(string? group = null, string? culture = null); /// /// Gets all tags attached to an entity via a property. /// - IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string group = null, string? culture = null); + IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string? group = null, string? culture = null); /// /// Gets all tags attached to an entity. /// - IEnumerable GetTagsForEntity(int contentId, string group = null, string? culture = null); + IEnumerable GetTagsForEntity(int contentId, string? group = null, string? culture = null); } } diff --git a/src/Umbraco.Core/PublishedCache/Internal/InternalPublishedContent.cs b/src/Umbraco.Core/PublishedCache/Internal/InternalPublishedContent.cs index 2c79e68e1d..7d5c0fdedd 100644 --- a/src/Umbraco.Core/PublishedCache/Internal/InternalPublishedContent.cs +++ b/src/Umbraco.Core/PublishedCache/Internal/InternalPublishedContent.cs @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.PublishedCache.Internal ContentType = contentType; } - private Dictionary _cultures; + private Dictionary? _cultures; private Dictionary GetCultures() => new Dictionary { { string.Empty, new PublishedCultureInfo(string.Empty, Name, UrlSegment, UpdateDate) } }; @@ -56,9 +56,9 @@ namespace Umbraco.Cms.Core.PublishedCache.Internal public PublishedItemType ItemType => PublishedItemType.Content; - public bool IsDraft(string culture = null) => false; + public bool IsDraft(string? culture = null) => false; - public bool IsPublished(string culture = null) => true; + public bool IsPublished(string? culture = null) => true; public int ParentId { get; set; } @@ -74,11 +74,11 @@ namespace Umbraco.Cms.Core.PublishedCache.Internal public IEnumerable Properties { get; set; } - public IPublishedProperty GetProperty(string alias) => Properties.FirstOrDefault(p => p.Alias.InvariantEquals(alias)); + public IPublishedProperty? GetProperty(string alias) => Properties.FirstOrDefault(p => p.Alias.InvariantEquals(alias)); - public IPublishedProperty GetProperty(string alias, bool recurse) + public IPublishedProperty? GetProperty(string alias, bool recurse) { - IPublishedProperty property = GetProperty(alias); + IPublishedProperty? property = GetProperty(alias); if (recurse == false) { return property; @@ -94,7 +94,7 @@ namespace Umbraco.Cms.Core.PublishedCache.Internal return property; } - public object this[string alias] + public object? this[string alias] { get { diff --git a/src/Umbraco.Core/PublishedCache/PublishedCacheBase.cs b/src/Umbraco.Core/PublishedCache/PublishedCacheBase.cs index dabe6d9305..9ffa3bb447 100644 --- a/src/Umbraco.Core/PublishedCache/PublishedCacheBase.cs +++ b/src/Umbraco.Core/PublishedCache/PublishedCacheBase.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.PublishedCache { public abstract class PublishedCacheBase : IPublishedCache { - private readonly IVariationContextAccessor _variationContextAccessor; + private readonly IVariationContextAccessor? _variationContextAccessor; public PublishedCacheBase(IVariationContextAccessor variationContextAccessor) { @@ -46,7 +46,7 @@ namespace Umbraco.Cms.Core.PublishedCache public abstract IEnumerable GetAtRoot(bool preview, string? culture = null); - public IEnumerable GetAtRoot(string culture = null) + public IEnumerable GetAtRoot(string? culture = null) { return GetAtRoot(PreviewDefault, culture); } @@ -104,7 +104,7 @@ namespace Umbraco.Cms.Core.PublishedCache // this is probably not super-efficient, but works // some cache implementation may want to override it, though return GetAtRoot() - .SelectMany(x => x.DescendantsOrSelf(_variationContextAccessor)) + .SelectMany(x => x.DescendantsOrSelf(_variationContextAccessor!)) .Where(x => x.ContentType.Id == contentType.Id); } } diff --git a/src/Umbraco.Core/PublishedCache/PublishedElement.cs b/src/Umbraco.Core/PublishedCache/PublishedElement.cs index 92e988fcca..80f61fac40 100644 --- a/src/Umbraco.Core/PublishedCache/PublishedElement.cs +++ b/src/Umbraco.Core/PublishedCache/PublishedElement.cs @@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.PublishedCache // initializes a new instance of the PublishedElement class // within the context of a published snapshot service (eg a published content property value) public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary values, bool previewing, - PropertyCacheLevel referenceCacheLevel, IPublishedSnapshotAccessor publishedSnapshotAccessor) + PropertyCacheLevel referenceCacheLevel, IPublishedSnapshotAccessor? publishedSnapshotAccessor) { if (key == Guid.Empty) throw new ArgumentException("Empty guid."); if (values == null) throw new ArgumentNullException(nameof(values)); @@ -32,7 +32,7 @@ namespace Umbraco.Cms.Core.PublishedCache values = GetCaseInsensitiveValueDictionary(values); _propertiesArray = contentType - .PropertyTypes + .PropertyTypes? .Select(propertyType => { values.TryGetValue(propertyType.Alias, out var value); @@ -72,14 +72,14 @@ namespace Umbraco.Cms.Core.PublishedCache #region Properties - private readonly IPublishedProperty[] _propertiesArray; + private readonly IPublishedProperty[]? _propertiesArray; - public IEnumerable Properties => _propertiesArray; + public IEnumerable? Properties => _propertiesArray; - public IPublishedProperty GetProperty(string alias) + public IPublishedProperty? GetProperty(string alias) { var index = ContentType.GetPropertyIndex(alias); - var property = index < 0 ? null : _propertiesArray[index]; + var property = index < 0 ? null : _propertiesArray?[index]; return property; } diff --git a/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs b/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs index 69b8b4f73e..c6fe365be8 100644 --- a/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs +++ b/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs @@ -9,17 +9,17 @@ namespace Umbraco.Cms.Core.PublishedCache internal class PublishedElementPropertyBase : PublishedPropertyBase { private readonly object _locko = new object(); - private readonly object _sourceValue; - private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly object? _sourceValue; + private readonly IPublishedSnapshotAccessor? _publishedSnapshotAccessor; protected readonly IPublishedElement Element; protected readonly bool IsPreviewing; protected readonly bool IsMember; private bool _interInitialized; - private object _interValue; - private CacheValues _cacheValues; - private string _valuesCacheKey; + private object? _interValue; + private CacheValues? _cacheValues; + private string? _valuesCacheKey; // define constant - determines whether to use cache when previewing // to store eg routes, property converted values, anything - caching @@ -27,17 +27,17 @@ namespace Umbraco.Cms.Core.PublishedCache // so making it configurable. private const bool FullCacheWhenPreviewing = true; - public PublishedElementPropertyBase(IPublishedPropertyType propertyType, IPublishedElement element, bool previewing, PropertyCacheLevel referenceCacheLevel, object sourceValue = null, IPublishedSnapshotAccessor publishedSnapshotAccessor = null) + public PublishedElementPropertyBase(IPublishedPropertyType propertyType, IPublishedElement element, bool previewing, PropertyCacheLevel referenceCacheLevel, object? sourceValue = null, IPublishedSnapshotAccessor? publishedSnapshotAccessor = null) : base(propertyType, referenceCacheLevel) { _sourceValue = sourceValue; _publishedSnapshotAccessor = publishedSnapshotAccessor; Element = element; IsPreviewing = previewing; - IsMember = propertyType.ContentType.ItemType == PublishedItemType.Member; + IsMember = propertyType.ContentType?.ItemType == PublishedItemType.Member; } - public override bool HasValue(string culture = null, string? segment = null) + public override bool HasValue(string? culture = null, string? segment = null) { var hasValue = PropertyType.IsValue(_sourceValue, PropertyValueLevel.Source); if (hasValue.HasValue) return hasValue.Value; @@ -70,9 +70,9 @@ namespace Umbraco.Cms.Core.PublishedCache protected class CacheValues { public bool ObjectInitialized; - public object ObjectValue; + public object? ObjectValue; public bool XPathInitialized; - public object XPathValue; + public object? XPathValue; } public static string PropertyCacheValues(Guid contentUid, string typeAlias, bool previewing) => "PublishedSnapshot.Property.CacheValues[" + (previewing ? "D:" : "P:") + contentUid + ":" + typeAlias + "]"; @@ -104,19 +104,25 @@ namespace Umbraco.Cms.Core.PublishedCache } } - private IAppCache GetSnapshotCache() + private IAppCache? GetSnapshotCache() { // cache within the snapshot cache, unless previewing, then use the snapshot or // elements cache (if we don't want to pollute the elements cache with short-lived // data) depending on settings // for members, always cache in the snapshot cache - never pollute elements cache + if (_publishedSnapshotAccessor is null) + { + return null; + } + if (!_publishedSnapshotAccessor.TryGetPublishedSnapshot(out var publishedSnapshot)) { return null; } + return (IsPreviewing == false || FullCacheWhenPreviewing) && IsMember == false - ? publishedSnapshot.ElementsCache - : publishedSnapshot.SnapshotCache; + ? publishedSnapshot!.ElementsCache + : publishedSnapshot!.SnapshotCache; } private CacheValues GetCacheValues(PropertyCacheLevel cacheLevel) @@ -135,13 +141,13 @@ namespace Umbraco.Cms.Core.PublishedCache case PropertyCacheLevel.Elements: // cache within the elements cache, depending... var snapshotCache = GetSnapshotCache(); - cacheValues = (CacheValues) snapshotCache?.Get(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues(); + cacheValues = (CacheValues?) snapshotCache?.Get(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues(); break; case PropertyCacheLevel.Snapshot: - var publishedSnapshot = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot(); + var publishedSnapshot = _publishedSnapshotAccessor?.GetRequiredPublishedSnapshot(); // cache within the snapshot cache - var facadeCache = publishedSnapshot.SnapshotCache; - cacheValues = (CacheValues) facadeCache?.Get(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues(); + var facadeCache = publishedSnapshot?.SnapshotCache; + cacheValues = (CacheValues?) facadeCache?.Get(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues(); break; default: throw new InvalidOperationException("Invalid cache level."); @@ -149,7 +155,7 @@ namespace Umbraco.Cms.Core.PublishedCache return cacheValues; } - private object GetInterValue() + private object? GetInterValue() { if (_interInitialized) return _interValue; @@ -158,9 +164,9 @@ namespace Umbraco.Cms.Core.PublishedCache return _interValue; } - public override object GetSourceValue(string culture = null, string? segment = null) => _sourceValue; + public override object? GetSourceValue(string? culture = null, string? segment = null) => _sourceValue; - public override object GetValue(string culture = null, string? segment = null) + public override object? GetValue(string? culture = null, string? segment = null) { GetCacheLevels(out var cacheLevel, out var referenceCacheLevel); @@ -174,7 +180,7 @@ namespace Umbraco.Cms.Core.PublishedCache } } - public override object GetXPathValue(string culture = null, string? segment = null) + public override object? GetXPathValue(string? culture = null, string? segment = null) { GetCacheLevels(out var cacheLevel, out var referenceCacheLevel); diff --git a/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs b/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs index 4d8c823b6a..7f81d066f2 100644 --- a/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs +++ b/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs @@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core.PublishedCache _umbracoContextAccessor = umbracoContextAccessor; } - public IPublishedSnapshot PublishedSnapshot + public IPublishedSnapshot? PublishedSnapshot { get { @@ -25,20 +25,20 @@ namespace Umbraco.Cms.Core.PublishedCache { return null; } - return umbracoContext.PublishedSnapshot; + return umbracoContext?.PublishedSnapshot; } set => throw new NotSupportedException(); // not ok to set } - public bool TryGetPublishedSnapshot(out IPublishedSnapshot publishedSnapshot) + public bool TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) { if (!_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) { publishedSnapshot = null; return false; } - publishedSnapshot = umbracoContext.PublishedSnapshot; + publishedSnapshot = umbracoContext?.PublishedSnapshot; return publishedSnapshot is not null; } diff --git a/src/Umbraco.Core/ReflectionUtilities.cs b/src/Umbraco.Core/ReflectionUtilities.cs index 01f373387f..7a43ed04a6 100644 --- a/src/Umbraco.Core/ReflectionUtilities.cs +++ b/src/Umbraco.Core/ReflectionUtilities.cs @@ -152,7 +152,7 @@ namespace Umbraco.Cms.Core /// or /// Value type does not match property . type. /// Could not find property getter for .. - public static Func EmitPropertyGetter(string propertyName, bool mustExist = true) + public static Func? EmitPropertyGetter(string propertyName, bool mustExist = true) { if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(propertyName)); @@ -183,7 +183,7 @@ namespace Umbraco.Cms.Core /// or /// Value type does not match property . type. /// Could not find property setter for .. - public static Action EmitPropertySetter(string propertyName, bool mustExist = true) + public static Action? EmitPropertySetter(string propertyName, bool mustExist = true) { if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(propertyName)); @@ -334,7 +334,7 @@ namespace Umbraco.Cms.Core /// Occurs when the constructor does not exist and is true. /// Occurs when is not a Func or when /// is specified and does not match the function's returned type. - public static TLambda EmitConstructor(bool mustExist = true, Type declaring = null) + public static TLambda? EmitConstructor(bool mustExist = true, Type? declaring = null) { var (_, lambdaParameters, lambdaReturned) = AnalyzeLambda(true, true); @@ -416,7 +416,7 @@ namespace Umbraco.Cms.Core return EmitConstructor(lambdaReturned, lambdaParameters, ctor); } - private static TLambda EmitConstructor(Type declaring, Type[] lambdaParameters, ConstructorInfo ctor) + private static TLambda EmitConstructor(Type? declaring, Type[] lambdaParameters, ConstructorInfo ctor) { // gets the method argument types var ctorParameters = GetParameters(ctor); @@ -452,7 +452,7 @@ namespace Umbraco.Cms.Core /// /// The method arguments are determined by generic arguments. /// - public static TLambda EmitMethod(string methodName, bool mustExist = true) + public static TLambda? EmitMethod(string methodName, bool mustExist = true) { return EmitMethod(typeof(TDeclaring), methodName, mustExist); } @@ -475,7 +475,7 @@ namespace Umbraco.Cms.Core /// /// The method arguments are determined by generic arguments. /// - public static TLambda EmitMethod(Type declaring, string methodName, bool mustExist = true) + public static TLambda? EmitMethod(Type declaring, string methodName, bool mustExist = true) { if (methodName == null) throw new ArgumentNullException(nameof(methodName)); if (string.IsNullOrWhiteSpace(methodName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(methodName)); @@ -569,7 +569,7 @@ namespace Umbraco.Cms.Core /// /// The method arguments are determined by generic arguments. /// - public static TLambda EmitMethod(string methodName, bool mustExist = true) + public static TLambda? EmitMethod(string methodName, bool mustExist = true) { if (methodName == null) throw new ArgumentNullException(nameof(methodName)); if (string.IsNullOrWhiteSpace(methodName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(methodName)); @@ -578,7 +578,7 @@ namespace Umbraco.Cms.Core var (lambdaDeclaring, lambdaParameters, lambdaReturned) = AnalyzeLambda(false, out var isFunction); // get the method infos - var method = lambdaDeclaring.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, lambdaParameters, null); + var method = lambdaDeclaring?.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, lambdaParameters, null); if (method == null || isFunction && method.ReturnType != lambdaReturned) { if (!mustExist) return default; @@ -591,7 +591,7 @@ namespace Umbraco.Cms.Core // lambdaReturned = the lambda returned type (can be void) // lambdaArgTypes = the lambda argument types - private static TLambda EmitMethod(Type lambdaDeclaring, Type lambdaReturned, Type[] lambdaParameters, MethodInfo method) + private static TLambda EmitMethod(Type? lambdaDeclaring, Type lambdaReturned, Type[] lambdaParameters, MethodInfo method) { // non-static methods need the declaring type as first arg var parameters = lambdaParameters; @@ -624,7 +624,7 @@ namespace Umbraco.Cms.Core // hence, when !isStatic, the lambda cannot be a simple Action, as it requires at least one generic argument // when isFunction, the last generic argument of the lambda is the returned type // everything in between is parameters - private static (Type Declaring, Type[] Parameters, Type Returned) AnalyzeLambda(bool isStatic, bool isFunction) + private static (Type? Declaring, Type[] Parameters, Type Returned) AnalyzeLambda(bool isStatic, bool isFunction) { var typeLambda = typeof(TLambda); @@ -648,7 +648,7 @@ namespace Umbraco.Cms.Core // hence, when !isStatic, the lambda cannot be a simple Action, as it requires at least one generic argument // when isFunction, the last generic argument of the lambda is the returned type // everything in between is parameters - private static (Type Declaring, Type[] Parameters, Type Returned) AnalyzeLambda(bool isStatic, out bool isFunction) + private static (Type? Declaring, Type[] Parameters, Type Returned) AnalyzeLambda(bool isStatic, out bool isFunction) { isFunction = false; @@ -695,7 +695,7 @@ namespace Umbraco.Cms.Core return (declaring, parameters, returned); } - private static (DynamicMethod, ILGenerator) CreateIlGenerator(Module module, Type[] arguments, Type returned) + private static (DynamicMethod, ILGenerator) CreateIlGenerator(Module? module, Type[] arguments, Type? returned) { if (module == null) throw new ArgumentNullException(nameof(module)); var dm = new DynamicMethod(string.Empty, returned, arguments, module, true); @@ -832,8 +832,8 @@ namespace Umbraco.Cms.Core // return o is T t ? t : (T) System.Convert.ChangeType(o, typeof(T)); //} - private static MethodInfo _convertMethod; - private static MethodInfo _getTypeFromHandle; + private static MethodInfo? _convertMethod; + private static MethodInfo? _getTypeFromHandle; private static void Convert(this ILGenerator ilgen, Type type) { @@ -895,15 +895,18 @@ namespace Umbraco.Cms.Core } } - private static void ThrowInvalidLambda(string methodName, Type returned, Type[] args) + private static void ThrowInvalidLambda(string methodName, Type? returned, Type[] args) { throw new ArgumentException($"Lambda {typeof(TLambda)} does not match {methodName}({string.Join(", ", (IEnumerable) args)}):{returned}.", nameof(TLambda)); } - private static void CallMethod(this ILGenerator ilgen, MethodInfo method) + private static void CallMethod(this ILGenerator ilgen, MethodInfo? method) { - var virt = !method.IsStatic && (method.IsVirtual || !method.IsFinal); - ilgen.Emit(virt ? OpCodes.Callvirt : OpCodes.Call, method); + if (method is not null) + { + var virt = !method.IsStatic && (method.IsVirtual || !method.IsFinal); + ilgen.Emit(virt ? OpCodes.Callvirt : OpCodes.Call, method); + } } private static void Return(this ILGenerator ilgen) diff --git a/src/Umbraco.Core/Routing/AliasUrlProvider.cs b/src/Umbraco.Core/Routing/AliasUrlProvider.cs index 6f6181da21..98160aab1a 100644 --- a/src/Umbraco.Core/Routing/AliasUrlProvider.cs +++ b/src/Umbraco.Core/Routing/AliasUrlProvider.cs @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Routing #region GetUrl /// - public UrlInfo GetUrl(IPublishedContent content, UrlMode mode, string culture, Uri current) + public UrlInfo? GetUrl(IPublishedContent content, UrlMode mode, string? culture, Uri current) { return null; // we have nothing to say } @@ -79,7 +79,7 @@ namespace Umbraco.Cms.Core.Routing } // determine whether the alias property varies - var varies = node.GetProperty(Constants.Conventions.Content.UrlAlias).PropertyType.VariesByCulture(); + var varies = node.GetProperty(Constants.Conventions.Content.UrlAlias)!.PropertyType.VariesByCulture(); if (domainUris == null) { diff --git a/src/Umbraco.Core/Routing/ContentFinderByIdPath.cs b/src/Umbraco.Core/Routing/ContentFinderByIdPath.cs index 1ff54c1546..daaf84ebe8 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByIdPath.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByIdPath.cs @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Core.Routing return false; } - IPublishedContent node = null; + IPublishedContent? node = null; var path = frequest.AbsolutePathDecoded; var nodeId = -1; @@ -71,7 +71,7 @@ namespace Umbraco.Cms.Core.Routing if (nodeId > 0) { _logger.LogDebug("Id={NodeId}", nodeId); - node = umbracoContext.Content.GetById(nodeId); + node = umbracoContext?.Content.GetById(nodeId); if (node != null) { diff --git a/src/Umbraco.Core/Routing/ContentFinderByPageIdQuery.cs b/src/Umbraco.Core/Routing/ContentFinderByPageIdQuery.cs index 7a71cfc5cd..912381f6c4 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByPageIdQuery.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByPageIdQuery.cs @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core.Routing } if (int.TryParse(_requestAccessor.GetRequestValue("umbPageID"), NumberStyles.Integer, CultureInfo.InvariantCulture, out int pageId)) { - IPublishedContent doc = umbracoContext.Content.GetById(pageId); + IPublishedContent? doc = umbracoContext?.Content.GetById(pageId); if (doc != null) { diff --git a/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs index a47fa34e96..373e9b26c1 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByRedirectUrl.cs @@ -62,7 +62,7 @@ namespace Umbraco.Cms.Core.Routing return false; } - IPublishedContent content = umbracoContext.Content.GetById(redirectUrl.ContentId); + IPublishedContent? content = umbracoContext?.Content.GetById(redirectUrl.ContentId); var url = content == null ? "#" : content.Url(_publishedUrlProvider, redirectUrl.Culture); if (url.StartsWith("#")) { @@ -73,7 +73,7 @@ namespace Umbraco.Cms.Core.Routing // Appending any querystring from the incoming request to the redirect URL url = string.IsNullOrEmpty(frequest.Uri.Query) ? url : url + frequest.Uri.Query; - _logger.LogDebug("Route {Route} matches content {ContentId} with URL '{Url}', redirecting.", route, content.Id, url); + _logger.LogDebug("Route {Route} matches content {ContentId} with URL '{Url}', redirecting.", route, content?.Id, url); frequest .SetRedirectPermanent(url) diff --git a/src/Umbraco.Core/Routing/ContentFinderByUrl.cs b/src/Umbraco.Core/Routing/ContentFinderByUrl.cs index 9174ed999a..b338e03bbf 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByUrl.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByUrl.cs @@ -50,7 +50,7 @@ namespace Umbraco.Cms.Core.Routing route = frequest.AbsolutePathDecoded; } - IPublishedContent node = FindContent(frequest, route); + IPublishedContent? node = FindContent(frequest, route); return node != null; } @@ -58,7 +58,7 @@ namespace Umbraco.Cms.Core.Routing /// Tries to find an Umbraco document for a PublishedRequest and a route. /// /// The document node, or null. - protected IPublishedContent FindContent(IPublishedRequestBuilder docreq, string route) + protected IPublishedContent? FindContent(IPublishedRequestBuilder docreq, string route) { if (!UmbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) { @@ -72,7 +72,7 @@ namespace Umbraco.Cms.Core.Routing _logger.LogDebug("Test route {Route}", route); - IPublishedContent node = umbracoContext.Content.GetByRoute(umbracoContext.InPreviewMode, route, culture: docreq.Culture); + IPublishedContent? node = umbracoContext?.Content.GetByRoute(umbracoContext.InPreviewMode, route, culture: docreq.Culture); if (node != null) { docreq.SetPublishedContent(node); diff --git a/src/Umbraco.Core/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Core/Routing/ContentFinderByUrlAlias.cs index f93ef013d8..6c1e9198de 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByUrlAlias.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByUrlAlias.cs @@ -48,13 +48,13 @@ namespace Umbraco.Cms.Core.Routing { return false; } - IPublishedContent node = null; + IPublishedContent? node = null; // no alias if "/" if (frequest.Uri.AbsolutePath != "/") { node = FindContentByAlias( - umbracoContext.Content, + umbracoContext!.Content, frequest.Domain != null ? frequest.Domain.ContentId : 0, frequest.Culture, frequest.AbsolutePathDecoded); @@ -69,7 +69,7 @@ namespace Umbraco.Cms.Core.Routing return node != null; } - private IPublishedContent FindContentByAlias(IPublishedContentCache cache, int rootNodeId, string culture, string alias) + private IPublishedContent? FindContentByAlias(IPublishedContentCache cache, int rootNodeId, string? culture, string alias) { if (alias == null) { @@ -101,9 +101,9 @@ namespace Umbraco.Cms.Core.Routing return false; } - IPublishedProperty p = c.GetProperty(propertyAlias); - var varies = p.PropertyType.VariesByCulture(); - string v; + IPublishedProperty? p = c.GetProperty(propertyAlias); + var varies = p!.PropertyType.VariesByCulture(); + string? v; if (varies) { if (!c.HasCulture(culture)) @@ -137,7 +137,7 @@ namespace Umbraco.Cms.Core.Routing foreach (IPublishedContent rootContent in cache.GetAtRoot()) { - IPublishedContent c = rootContent.DescendantsOrSelf(_variationContextAccessor).FirstOrDefault(x => IsMatch(x, test1, test2)); + IPublishedContent? c = rootContent.DescendantsOrSelf(_variationContextAccessor).FirstOrDefault(x => IsMatch(x, test1, test2)); if (c != null) { return c; diff --git a/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs b/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs index f8eb328eed..2810d46393 100644 --- a/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs +++ b/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs @@ -82,7 +82,7 @@ namespace Umbraco.Cms.Core.Routing // look for node corresponding to the rest of the route var route = frequest.Domain != null ? (frequest.Domain.ContentId + path) : path; - IPublishedContent node = FindContent(frequest, route); + IPublishedContent? node = FindContent(frequest, route); if (node == null) { diff --git a/src/Umbraco.Core/Routing/DefaultMediaUrlProvider.cs b/src/Umbraco.Core/Routing/DefaultMediaUrlProvider.cs index 821a5c9013..1afda0175c 100644 --- a/src/Umbraco.Core/Routing/DefaultMediaUrlProvider.cs +++ b/src/Umbraco.Core/Routing/DefaultMediaUrlProvider.cs @@ -19,8 +19,8 @@ namespace Umbraco.Cms.Core.Routing } /// - public virtual UrlInfo GetMediaUrl(IPublishedContent content, - string propertyAlias, UrlMode mode, string culture, Uri current) + public virtual UrlInfo? GetMediaUrl(IPublishedContent content, + string propertyAlias, UrlMode mode, string? culture, Uri current) { var prop = content.GetProperty(propertyAlias); @@ -31,11 +31,11 @@ namespace Umbraco.Cms.Core.Routing return null; } - var propType = prop.PropertyType; + var propType = prop?.PropertyType; - if (_mediaPathGenerators.TryGetMediaPath(propType.EditorAlias, value, out var path)) + if (_mediaPathGenerators.TryGetMediaPath(propType?.EditorAlias, value, out var path)) { - var url = AssembleUrl(path, current, mode); + var url = AssembleUrl(path!, current, mode); return UrlInfo.Url(url.ToString(), culture); } diff --git a/src/Umbraco.Core/Routing/DefaultUrlProvider.cs b/src/Umbraco.Core/Routing/DefaultUrlProvider.cs index 2a7bc97650..1bad73edc9 100644 --- a/src/Umbraco.Core/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Core/Routing/DefaultUrlProvider.cs @@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.Routing public class DefaultUrlProvider : IUrlProvider { private readonly ILocalizationService _localizationService; - private readonly ILocalizedTextService _localizedTextService; + private readonly ILocalizedTextService? _localizedTextService; private readonly ILogger _logger; private RequestHandlerSettings _requestSettings; private readonly ISiteDomainMapper _siteDomainMapper; @@ -78,7 +78,7 @@ namespace Umbraco.Cms.Core.Routing // look for domains, walking up the tree IPublishedContent n = node; - IEnumerable domainUris = + IEnumerable? domainUris = DomainUtilities.DomainsForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, n.Id, current, false); while (domainUris == null && n != null) // n is null at root @@ -98,7 +98,7 @@ namespace Umbraco.Cms.Core.Routing foreach (DomainAndUri d in domainUris) { - var culture = d?.Culture; + var culture = d.Culture; // although we are passing in culture here, if any node in this path is invariant, it ignores the culture anyways so this is ok var route = umbracoContext.Content.GetRouteById(id, culture); @@ -122,7 +122,7 @@ namespace Umbraco.Cms.Core.Routing #region GetUrl /// - public virtual UrlInfo GetUrl(IPublishedContent content, UrlMode mode, string culture, Uri current) + public virtual UrlInfo? GetUrl(IPublishedContent content, UrlMode mode, string? culture, Uri current) { if (!current.IsAbsoluteUri) { @@ -136,8 +136,8 @@ namespace Umbraco.Cms.Core.Routing return GetUrlFromRoute(route, umbracoContext, content.Id, current, mode, culture); } - internal UrlInfo GetUrlFromRoute(string route, IUmbracoContext umbracoContext, int id, Uri current, - UrlMode mode, string culture) + internal UrlInfo? GetUrlFromRoute(string? route, IUmbracoContext umbracoContext, int id, Uri current, + UrlMode mode, string? culture) { if (string.IsNullOrWhiteSpace(route)) { @@ -169,7 +169,7 @@ namespace Umbraco.Cms.Core.Routing #region Utilities - private Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlMode mode) + private Uri AssembleUrl(DomainAndUri? domainUri, string path, Uri current, UrlMode mode) { Uri uri; @@ -185,7 +185,7 @@ namespace Umbraco.Cms.Core.Routing switch (mode) { case UrlMode.Absolute: - uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path); + uri = new Uri(current!.GetLeftPart(UriPartial.Authority) + path); break; case UrlMode.Relative: case UrlMode.Auto: diff --git a/src/Umbraco.Core/Routing/DomainUtilities.cs b/src/Umbraco.Core/Routing/DomainUtilities.cs index 1c43a72fd3..2b8e84d703 100644 --- a/src/Umbraco.Core/Routing/DomainUtilities.cs +++ b/src/Umbraco.Core/Routing/DomainUtilities.cs @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.Routing /// one document per culture), and domains, withing the context of a current Uri, assign /// a culture to that document. /// - public static string GetCultureFromDomains(int contentId, string contentPath, Uri current, IUmbracoContext umbracoContext, ISiteDomainMapper siteDomainMapper) + public static string? GetCultureFromDomains(int contentId, string contentPath, Uri current, IUmbracoContext umbracoContext, ISiteDomainMapper siteDomainMapper) { if (umbracoContext == null) throw new InvalidOperationException("A current UmbracoContext is required."); @@ -77,7 +77,7 @@ namespace Umbraco.Cms.Core.Routing /// If culture is null, uses the default culture for the installation instead. Otherwise, /// will try with the specified culture, else return null. /// - internal static DomainAndUri DomainForNode(IDomainCache domainCache, ISiteDomainMapper siteDomainMapper, int nodeId, Uri current, string? culture = null) + internal static DomainAndUri? DomainForNode(IDomainCache domainCache, ISiteDomainMapper siteDomainMapper, int nodeId, Uri current, string? culture = null) { // be safe if (nodeId <= 0) @@ -106,7 +106,7 @@ namespace Umbraco.Cms.Core.Routing /// The domains and their uris, that match the specified uri, else null. /// If at least a domain is set on the node then the method returns the domains that /// best match the specified uri, else it returns null. - internal static IEnumerable DomainsForNode(IDomainCache domainCache, ISiteDomainMapper siteDomainMapper, int nodeId, Uri current, bool excludeDefault = true) + internal static IEnumerable? DomainsForNode(IDomainCache domainCache, ISiteDomainMapper siteDomainMapper, int nodeId, Uri current, bool excludeDefault = true) { // be safe if (nodeId <= 0) @@ -148,7 +148,7 @@ namespace Umbraco.Cms.Core.Routing /// the right one, unless it is null, in which case the method returns null. /// The filter, if any, will be called only with a non-empty argument, and _must_ return something. /// - public static DomainAndUri SelectDomain(IEnumerable domains, Uri uri, string? culture = null, string defaultCulture = null, Func, Uri, string, string, DomainAndUri> filter = null) + public static DomainAndUri? SelectDomain(IEnumerable domains, Uri uri, string? culture = null, string? defaultCulture = null, Func, Uri, string?, string?, DomainAndUri?>? filter = null) { // sanitize the list to have proper uris for comparison (scheme, path end with /) // we need to end with / because example.com/foo cannot match example.com/foobar @@ -164,8 +164,8 @@ namespace Umbraco.Cms.Core.Routing return null; // sanitize cultures - culture = culture.NullOrWhiteSpaceAsNull(); - defaultCulture = defaultCulture.NullOrWhiteSpaceAsNull(); + culture = culture?.NullOrWhiteSpaceAsNull(); + defaultCulture = defaultCulture?.NullOrWhiteSpaceAsNull(); if (uri == null) { @@ -209,10 +209,10 @@ namespace Umbraco.Cms.Core.Routing private static bool IsBaseOf(DomainAndUri domain, Uri uri) => domain.Uri.EndPathWithSlash().IsBaseOf(uri); - private static bool MatchesCulture(DomainAndUri domain, string culture) + private static bool MatchesCulture(DomainAndUri domain, string? culture) => culture == null || domain.Culture.InvariantEquals(culture); - private static IReadOnlyCollection SelectByBase(IReadOnlyCollection domainsAndUris, Uri uri, string culture) + private static IReadOnlyCollection SelectByBase(IReadOnlyCollection domainsAndUris, Uri uri, string? culture) { // look for domains that would be the base of the uri // ie current is www.example.com/foo/bar, look for domain www.example.com @@ -228,7 +228,7 @@ namespace Umbraco.Cms.Core.Routing return baseDomains; } - private static IReadOnlyCollection SelectByCulture(IReadOnlyCollection domainsAndUris, string culture, string defaultCulture) + private static IReadOnlyCollection? SelectByCulture(IReadOnlyCollection domainsAndUris, string? culture, string? defaultCulture) { // we try our best to match cultures, but may end with a bogus domain @@ -247,9 +247,9 @@ namespace Umbraco.Cms.Core.Routing return null; } - private static DomainAndUri GetByCulture(IReadOnlyCollection domainsAndUris, string culture, string defaultCulture) + private static DomainAndUri GetByCulture(IReadOnlyCollection domainsAndUris, string? culture, string? defaultCulture) { - DomainAndUri domainAndUri; + DomainAndUri? domainAndUri; // we try our best to match cultures, but may end with a bogus domain @@ -324,7 +324,7 @@ namespace Umbraco.Cms.Core.Routing /// The current domain root node identifier, or null. /// The deepest non-wildcard Domain in the path, or null. /// Looks _under_ rootNodeId but not _at_ rootNodeId. - internal static Domain FindDomainInPath(IEnumerable domains, string path, int? rootNodeId) + internal static Domain? FindDomainInPath(IEnumerable domains, string path, int? rootNodeId) { var stopNodeId = rootNodeId ?? -1; @@ -345,7 +345,7 @@ namespace Umbraco.Cms.Core.Routing /// The current domain root node identifier, or null. /// The deepest wildcard Domain in the path, or null. /// Looks _under_ rootNodeId but not _at_ rootNodeId. - public static Domain FindWildcardDomainInPath(IEnumerable domains, string path, int? rootNodeId) + public static Domain? FindWildcardDomainInPath(IEnumerable domains, string path, int? rootNodeId) { var stopNodeId = rootNodeId ?? -1; diff --git a/src/Umbraco.Core/Routing/IMediaUrlProvider.cs b/src/Umbraco.Core/Routing/IMediaUrlProvider.cs index 918c7362f3..4478f60334 100644 --- a/src/Umbraco.Core/Routing/IMediaUrlProvider.cs +++ b/src/Umbraco.Core/Routing/IMediaUrlProvider.cs @@ -25,6 +25,6 @@ namespace Umbraco.Cms.Core.Routing /// e.g. a cdn URL provider will most likely always return an absolute URL. /// If the provider is unable to provide a URL, it returns null. /// - UrlInfo GetMediaUrl(IPublishedContent content, string propertyAlias, UrlMode mode, string culture, Uri current); + UrlInfo? GetMediaUrl(IPublishedContent content, string propertyAlias, UrlMode mode, string? culture, Uri current); } } diff --git a/src/Umbraco.Core/Routing/IPublishedRequest.cs b/src/Umbraco.Core/Routing/IPublishedRequest.cs index 17b836779e..9f68c618d2 100644 --- a/src/Umbraco.Core/Routing/IPublishedRequest.cs +++ b/src/Umbraco.Core/Routing/IPublishedRequest.cs @@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets a value indicating the requested content. /// - IPublishedContent PublishedContent { get; } + IPublishedContent? PublishedContent { get; } /// /// Gets a value indicating whether the current published content has been obtained @@ -37,14 +37,14 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets the template assigned to the request (if any) /// - ITemplate Template { get; } + ITemplate? Template { get; } /// /// Gets the content request's domain. /// /// Is a DomainAndUri object ie a standard Domain plus the fully qualified uri. For example, /// the Domain may contain "example.com" whereas the Uri will be fully qualified eg "http://example.com/". - DomainAndUri Domain { get; } + DomainAndUri? Domain { get; } /// /// Gets the content request's culture. @@ -53,12 +53,12 @@ namespace Umbraco.Cms.Core.Routing /// This will get mapped to a CultureInfo eventually but CultureInfo are expensive to create so we want to leave that up to the /// localization middleware to do. See https://github.com/dotnet/aspnetcore/blob/b795ac3546eb3e2f47a01a64feb3020794ca33bb/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs#L165. /// - string Culture { get; } + string? Culture { get; } /// /// Gets the url to redirect to, when the content request triggers a redirect. /// - string RedirectUrl { get; } + string? RedirectUrl { get; } /// /// Gets the content request http response status code. @@ -70,12 +70,12 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets a list of Extensions to append to the Response.Cache object. /// - IReadOnlyList CacheExtensions { get; } + IReadOnlyList? CacheExtensions { get; } /// /// Gets a dictionary of Headers to append to the Response object. /// - IReadOnlyDictionary Headers { get; } + IReadOnlyDictionary? Headers { get; } /// /// Gets a value indicating whether the no-cache value should be added to the Cache-Control header diff --git a/src/Umbraco.Core/Routing/IPublishedRequestBuilder.cs b/src/Umbraco.Core/Routing/IPublishedRequestBuilder.cs index 3c6f614d60..44054a7ab4 100644 --- a/src/Umbraco.Core/Routing/IPublishedRequestBuilder.cs +++ b/src/Umbraco.Core/Routing/IPublishedRequestBuilder.cs @@ -26,12 +26,12 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets the assigned (if any) /// - DomainAndUri Domain { get; } + DomainAndUri? Domain { get; } /// /// Gets the assigned (if any) /// - string Culture { get; } + string? Culture { get; } /// /// Gets a value indicating whether the current published content has been obtained @@ -49,12 +49,12 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets the current assigned (if any) /// - IPublishedContent PublishedContent { get; } + IPublishedContent? PublishedContent { get; } /// /// Gets the template assigned to the request (if any) /// - ITemplate Template { get; } + ITemplate? Template { get; } /// /// Builds the @@ -75,7 +75,7 @@ namespace Umbraco.Cms.Core.Routing /// Sets the found for the request /// /// Setting the content clears the template and redirect - IPublishedRequestBuilder SetPublishedContent(IPublishedContent content); + IPublishedRequestBuilder SetPublishedContent(IPublishedContent? content); /// /// Sets the requested content, following an internal redirect. @@ -100,7 +100,7 @@ namespace Umbraco.Cms.Core.Routing /// /// The template. /// Setting the template does refresh RenderingEngine. - IPublishedRequestBuilder SetTemplate(ITemplate template); + IPublishedRequestBuilder SetTemplate(ITemplate? template); /// /// Indicates that the content request should trigger a permanent redirect (301). diff --git a/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs b/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs index 861fd63028..1a2ef5d508 100644 --- a/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs +++ b/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs @@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.Routing /// A culture. /// The current absolute url. /// The url for the published content. - string GetUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, Uri current = null); + string GetUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, Uri? current = null); /// /// Gets the url of a published content. @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.Routing /// A culture. /// The current absolute url. /// The url for the published content. - string GetUrl(int id, UrlMode mode = UrlMode.Default, string? culture = null, Uri current = null); + string GetUrl(int id, UrlMode mode = UrlMode.Default, string? culture = null, Uri? current = null); /// /// Gets the url of a published content. @@ -45,7 +45,7 @@ namespace Umbraco.Cms.Core.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a url, it returns "#". /// - string GetUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, Uri current = null); + string GetUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, Uri? current = null); string GetUrlFromRoute(int id, string? route, string? culture); @@ -82,7 +82,7 @@ namespace Umbraco.Cms.Core.Routing /// /// /// - string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null); + string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri? current = null); /// /// Gets the url of a media item. @@ -99,6 +99,6 @@ namespace Umbraco.Cms.Core.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a url, it returns . /// - string GetMediaUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null); + string GetMediaUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri? current = null); } } diff --git a/src/Umbraco.Core/Routing/ISiteDomainMapper.cs b/src/Umbraco.Core/Routing/ISiteDomainMapper.cs index 3ec280f007..56fdfaef6d 100644 --- a/src/Umbraco.Core/Routing/ISiteDomainMapper.cs +++ b/src/Umbraco.Core/Routing/ISiteDomainMapper.cs @@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.Routing /// to help pick the best matches. /// The filter _must_ return something else an exception will be thrown. /// - DomainAndUri MapDomain(IReadOnlyCollection domainAndUris, Uri current, string culture, string defaultCulture); + DomainAndUri? MapDomain(IReadOnlyCollection domainAndUris, Uri current, string? culture, string? defaultCulture); /// /// Filters a list of DomainAndUri to pick those that best matches the current request. @@ -40,6 +40,6 @@ namespace Umbraco.Cms.Core.Routing /// The may be null, but when non-null, it can be used /// to help pick the best matches. /// - IEnumerable MapDomains(IReadOnlyCollection domainAndUris, Uri current, bool excludeDefault, string culture, string defaultCulture); + IEnumerable MapDomains(IReadOnlyCollection domainAndUris, Uri current, bool excludeDefault, string? culture, string defaultCulture); } } diff --git a/src/Umbraco.Core/Routing/IUrlProvider.cs b/src/Umbraco.Core/Routing/IUrlProvider.cs index 257e471c05..0223b39c1d 100644 --- a/src/Umbraco.Core/Routing/IUrlProvider.cs +++ b/src/Umbraco.Core/Routing/IUrlProvider.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a URL, it should return null. /// - UrlInfo GetUrl(IPublishedContent content, UrlMode mode, string culture, Uri current); + UrlInfo? GetUrl(IPublishedContent content, UrlMode mode, string? culture, Uri current); /// /// Gets the other URLs of a published content. diff --git a/src/Umbraco.Core/Routing/PublishedRequest.cs b/src/Umbraco.Core/Routing/PublishedRequest.cs index 5667cb93e0..50328cbfdd 100644 --- a/src/Umbraco.Core/Routing/PublishedRequest.cs +++ b/src/Umbraco.Core/Routing/PublishedRequest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Initializes a new instance of the class. /// - public PublishedRequest(Uri uri, string absolutePathDecoded, IPublishedContent publishedContent, bool isInternalRedirect, ITemplate template, DomainAndUri domain, string culture, string redirectUrl, int? responseStatusCode, IReadOnlyList cacheExtensions, IReadOnlyDictionary headers, bool setNoCacheHeader, bool ignorePublishedContentCollisions) + public PublishedRequest(Uri uri, string absolutePathDecoded, IPublishedContent? publishedContent, bool isInternalRedirect, ITemplate? template, DomainAndUri? domain, string? culture, string? redirectUrl, int? responseStatusCode, IReadOnlyList? cacheExtensions, IReadOnlyDictionary? headers, bool setNoCacheHeader, bool ignorePublishedContentCollisions) { Uri = uri ?? throw new ArgumentNullException(nameof(uri)); AbsolutePathDecoded = absolutePathDecoded ?? throw new ArgumentNullException(nameof(absolutePathDecoded)); @@ -38,31 +38,31 @@ namespace Umbraco.Cms.Core.Routing public bool IgnorePublishedContentCollisions { get; } /// - public IPublishedContent PublishedContent { get; } + public IPublishedContent? PublishedContent { get; } /// public bool IsInternalRedirect { get; } /// - public ITemplate Template { get; } + public ITemplate? Template { get; } /// - public DomainAndUri Domain { get; } + public DomainAndUri? Domain { get; } /// - public string Culture { get; } + public string? Culture { get; } /// - public string RedirectUrl { get; } + public string? RedirectUrl { get; } /// public int? ResponseStatusCode { get; } /// - public IReadOnlyList CacheExtensions { get; } + public IReadOnlyList? CacheExtensions { get; } /// - public IReadOnlyDictionary Headers { get; } + public IReadOnlyDictionary? Headers { get; } /// public bool SetNoCacheHeader { get; } diff --git a/src/Umbraco.Core/Routing/PublishedRequestBuilder.cs b/src/Umbraco.Core/Routing/PublishedRequestBuilder.cs index 374412071c..a77dd88d71 100644 --- a/src/Umbraco.Core/Routing/PublishedRequestBuilder.cs +++ b/src/Umbraco.Core/Routing/PublishedRequestBuilder.cs @@ -12,12 +12,12 @@ namespace Umbraco.Cms.Core.Routing public class PublishedRequestBuilder : IPublishedRequestBuilder { private readonly IFileService _fileService; - private IReadOnlyDictionary _headers; + private IReadOnlyDictionary? _headers; private bool _cacheability; - private IReadOnlyList _cacheExtensions; - private string _redirectUrl; + private IReadOnlyList? _cacheExtensions; + private string? _redirectUrl; private HttpStatusCode? _responseStatus; - private IPublishedContent _publishedContent; + private IPublishedContent? _publishedContent; private bool _ignorePublishedContentCollisions; /// @@ -37,13 +37,13 @@ namespace Umbraco.Cms.Core.Routing public string AbsolutePathDecoded { get; } /// - public DomainAndUri Domain { get; private set; } + public DomainAndUri? Domain { get; private set; } /// - public string Culture { get; private set; } + public string? Culture { get; private set; } /// - public ITemplate Template { get; private set; } + public ITemplate? Template { get; private set; } /// public bool IsInternalRedirect { get; private set; } @@ -52,7 +52,7 @@ namespace Umbraco.Cms.Core.Routing public int? ResponseStatusCode => _responseStatus.HasValue ? (int?)_responseStatus : null; /// - public IPublishedContent PublishedContent + public IPublishedContent? PublishedContent { get => _publishedContent; private set @@ -139,7 +139,7 @@ namespace Umbraco.Cms.Core.Routing } /// - public IPublishedRequestBuilder SetPublishedContent(IPublishedContent content) + public IPublishedRequestBuilder SetPublishedContent(IPublishedContent? content) { PublishedContent = content; IsInternalRedirect = false; @@ -170,7 +170,7 @@ namespace Umbraco.Cms.Core.Routing } /// - public IPublishedRequestBuilder SetTemplate(ITemplate template) + public IPublishedRequestBuilder SetTemplate(ITemplate? template) { Template = template; return this; diff --git a/src/Umbraco.Core/Routing/PublishedRequestExtensions.cs b/src/Umbraco.Core/Routing/PublishedRequestExtensions.cs index 399347acb0..855bd53bde 100644 --- a/src/Umbraco.Core/Routing/PublishedRequestExtensions.cs +++ b/src/Umbraco.Core/Routing/PublishedRequestExtensions.cs @@ -61,7 +61,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets the alias of the template to use to display the requested content. /// - public static string GetTemplateAlias(this IPublishedRequest publishedRequest) => publishedRequest.Template?.Alias; + public static string? GetTemplateAlias(this IPublishedRequest publishedRequest) => publishedRequest.Template?.Alias; /// /// Gets a value indicating whether the requested content could not be found. diff --git a/src/Umbraco.Core/Routing/PublishedRequestOld.cs b/src/Umbraco.Core/Routing/PublishedRequestOld.cs index 7ee5cc35f2..44a75aaccd 100644 --- a/src/Umbraco.Core/Routing/PublishedRequestOld.cs +++ b/src/Umbraco.Core/Routing/PublishedRequestOld.cs @@ -18,15 +18,15 @@ namespace Umbraco.Cms.Core.Routing private bool _readonly; // after prepared private bool _is404; - private DomainAndUri _domain; - private CultureInfo _culture; - private IPublishedContent _publishedContent; - private IPublishedContent _initialPublishedContent; // found by finders before 404, redirects, etc + private DomainAndUri? _domain; + private CultureInfo? _culture; + private IPublishedContent? _publishedContent; + private IPublishedContent? _initialPublishedContent; // found by finders before 404, redirects, etc /// /// Initializes a new instance of the class. /// - public PublishedRequestOld(IPublishedRouter publishedRouter, IUmbracoContext umbracoContext, IOptions webRoutingSettings, Uri uri = null) + public PublishedRequestOld(IPublishedRouter publishedRouter, IUmbracoContext umbracoContext, IOptions webRoutingSettings, Uri? uri = null) { UmbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); _publishedRouter = publishedRouter ?? throw new ArgumentNullException(nameof(publishedRouter)); @@ -176,7 +176,7 @@ namespace Umbraco.Cms.Core.Routing /// /// The initial requested content is the content that was found by the finders, /// before anything such as 404, redirect... took place. - public IPublishedContent InitialPublishedContent => _initialPublishedContent; + public IPublishedContent? InitialPublishedContent => _initialPublishedContent; /// /// Gets value indicating whether the current published content is the initial one. @@ -209,12 +209,12 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets or sets the template model to use to display the requested content. /// - public ITemplate Template { get; } + public ITemplate? Template { get; } /// /// Gets the alias of the template to use to display the requested content. /// - public string TemplateAlias => Template?.Alias; + public string? TemplateAlias => Template?.Alias; /// @@ -222,7 +222,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Is a DomainAndUri object ie a standard Domain plus the fully qualified uri. For example, /// the Domain may contain "example.com" whereas the Uri will be fully qualified eg "http://example.com/". - public DomainAndUri Domain + public DomainAndUri? Domain { get { return _domain; } set @@ -285,7 +285,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Gets or sets the URL to redirect to, when the content request triggers a redirect. /// - public string RedirectUrl { get; private set; } + public string? RedirectUrl { get; private set; } /// /// Indicates that the content request should trigger a redirect (302). @@ -345,7 +345,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Does not actually set the http response status description, only registers that the response /// should use the specified description. The description will or will not be used, in due time. - public string ResponseStatusDescription { get; private set; } + public string? ResponseStatusDescription { get; private set; } /// /// Sets the http response status code, along with an optional associated description. @@ -355,7 +355,7 @@ namespace Umbraco.Cms.Core.Routing /// Does not actually set the http response status code and description, only registers that /// the response should use the specified code and description. The code and description will or will /// not be used, in due time. - public void SetResponseStatus(int code, string description = null) + public void SetResponseStatus(int code, string? description = null) { EnsureWriteable(); diff --git a/src/Umbraco.Core/Routing/PublishedRouter.cs b/src/Umbraco.Core/Routing/PublishedRouter.cs index 59896a8e43..b058798d94 100644 --- a/src/Umbraco.Core/Routing/PublishedRouter.cs +++ b/src/Umbraco.Core/Routing/PublishedRouter.cs @@ -114,9 +114,9 @@ namespace Umbraco.Cms.Core.Routing return request.Build(); } - private void SetVariationContext(string culture) + private void SetVariationContext(string? culture) { - VariationContext variationContext = _variationContextAccessor.VariationContext; + VariationContext? variationContext = _variationContextAccessor.VariationContext; if (variationContext != null && variationContext.Culture == culture) { return; @@ -229,7 +229,7 @@ namespace Umbraco.Cms.Core.Routing public async Task UpdateRequestAsync(IPublishedRequest request, IPublishedContent publishedContent) { // store the original (if any) - IPublishedContent content = request.PublishedContent; + IPublishedContent? content = request.PublishedContent; IPublishedRequestBuilder builder = new PublishedRequestBuilder(request.Uri, _fileService); @@ -305,7 +305,7 @@ namespace Umbraco.Cms.Core.Routing var defaultCulture = domainsCache.DefaultCulture; // try to find a domain matching the current request - DomainAndUri domainAndUri = DomainUtilities.SelectDomain(domains, request.Uri, defaultCulture: defaultCulture); + DomainAndUri? domainAndUri = DomainUtilities.SelectDomain(domains, request.Uri, defaultCulture: defaultCulture); // handle domain - always has a contentId and a culture if (domainAndUri != null) @@ -351,7 +351,7 @@ namespace Umbraco.Cms.Core.Routing _logger.LogDebug("{TracePrefix}Path={NodePath}", tracePrefix, nodePath); var rootNodeId = request.Domain != null ? request.Domain.ContentId : (int?)null; var umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext(); - Domain domain = DomainUtilities.FindWildcardDomainInPath(umbracoContext.PublishedSnapshot.Domains.GetAll(true), nodePath, rootNodeId); + Domain? domain = DomainUtilities.FindWildcardDomainInPath(umbracoContext.PublishedSnapshot.Domains.GetAll(true), nodePath, rootNodeId); // always has a contentId and a culture if (domain != null) @@ -376,7 +376,7 @@ namespace Umbraco.Cms.Core.Routing if (pos > 0) { // recurse - DirectoryInfo subdir = directory.GetDirectories(alias.Substring(0, pos)).FirstOrDefault(); + DirectoryInfo? subdir = directory.GetDirectories(alias.Substring(0, pos)).FirstOrDefault(); alias = alias.Substring(pos + 1); return subdir != null && FindTemplateRenderingEngineInDirectory(subdir, alias, extensions); } @@ -410,9 +410,9 @@ namespace Umbraco.Cms.Core.Routing _logger.LogDebug( "Found? {Found}, Content: {PublishedContentId}, Template: {TemplateAlias}, Domain: {Domain}, Culture: {Culture}, StatusCode: {StatusCode}", found, - request.HasPublishedContent() ? request.PublishedContent.Id : "NULL", + request.HasPublishedContent() ? request.PublishedContent?.Id : "NULL", request.HasTemplate() ? request.Template?.Alias : "NULL", - request.HasDomain() ? request.Domain.ToString() : "NULL", + request.HasDomain() ? request.Domain?.ToString() : "NULL", request.Culture ?? "NULL", request.ResponseStatusCode); @@ -502,7 +502,7 @@ namespace Umbraco.Cms.Core.Routing var redirect = false; var valid = false; - IPublishedContent internalRedirectNode = null; + IPublishedContent? internalRedirectNode = null; var internalRedirectId = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.InternalRedirectId, defaultValue: -1); var umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext(); @@ -514,8 +514,8 @@ namespace Umbraco.Cms.Core.Routing } else { - GuidUdi udiInternalRedirectId = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.InternalRedirectId); - if (udiInternalRedirectId != null) + GuidUdi? udiInternalRedirectId = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.InternalRedirectId); + if (udiInternalRedirectId is not null) { // try and get the redirect node from a UDI Guid valid = true; @@ -528,14 +528,14 @@ namespace Umbraco.Cms.Core.Routing // bad redirect - log and display the current page (legacy behavior) _logger.LogDebug( "FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: value is not an int nor a GuidUdi.", - request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()); + request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId)?.GetSourceValue()); } if (internalRedirectNode == null) { _logger.LogDebug( "FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: no such published document.", - request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()); + request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId)?.GetSourceValue()); } else if (internalRedirectId == request.PublishedContent.Id) { @@ -545,7 +545,7 @@ namespace Umbraco.Cms.Core.Routing else { // save since it will be cleared - ITemplate template = request.Template; + ITemplate? template = request.Template; request.SetInternalRedirect(internalRedirectNode); // don't use .PublishedContent here @@ -605,7 +605,7 @@ namespace Umbraco.Cms.Core.Routing // TODO: We need to limit altTemplate to only allow templates that are assigned to the current document type! // if the template isn't assigned to the document type we should log a warning and return 404 var templateId = request.PublishedContent.TemplateId; - ITemplate template = GetTemplate(templateId); + ITemplate? template = GetTemplate(templateId); request.SetTemplate(template); if (template != null) { @@ -657,9 +657,9 @@ namespace Umbraco.Cms.Core.Routing // no allowed, back to default var templateId = request.PublishedContent.TemplateId; - ITemplate template = GetTemplate(templateId); + ITemplate? template = GetTemplate(templateId); request.SetTemplate(template); - _logger.LogDebug("FindTemplate: Running with template id={TemplateId} alias={TemplateAlias}", template.Id, template.Alias); + _logger.LogDebug("FindTemplate: Running with template id={TemplateId} alias={TemplateAlias}", template?.Id, template?.Alias); } } @@ -678,7 +678,7 @@ namespace Umbraco.Cms.Core.Routing } } - private ITemplate GetTemplate(int? templateId) + private ITemplate? GetTemplate(int? templateId) { if (templateId.HasValue == false || templateId.Value == default) { @@ -729,8 +729,8 @@ namespace Umbraco.Cms.Core.Routing else { // might be a UDI instead of an int Id - GuidUdi redirectUdi = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.Redirect); - if (redirectUdi != null) + GuidUdi? redirectUdi = request.PublishedContent.Value(_publishedValueFallback, Constants.Conventions.Content.Redirect); + if (redirectUdi is not null) { redirectUrl = _publishedUrlProvider.GetUrl(redirectUdi.Guid); } diff --git a/src/Umbraco.Core/Routing/RouteRequestOptions.cs b/src/Umbraco.Core/Routing/RouteRequestOptions.cs index 6f987f072f..97792ebad3 100644 --- a/src/Umbraco.Core/Routing/RouteRequestOptions.cs +++ b/src/Umbraco.Core/Routing/RouteRequestOptions.cs @@ -18,7 +18,7 @@ namespace Umbraco.Cms.Core.Routing public RouteDirection RouteDirection { get; } /// - public override bool Equals(object obj) => obj is RouteRequestOptions options && Equals(options); + public override bool Equals(object? obj) => obj is RouteRequestOptions options && Equals(options); /// public bool Equals(RouteRequestOptions other) => RouteDirection == other.RouteDirection; diff --git a/src/Umbraco.Core/Routing/SiteDomainMapper.cs b/src/Umbraco.Core/Routing/SiteDomainMapper.cs index 455889d015..57c0dff3cf 100644 --- a/src/Umbraco.Core/Routing/SiteDomainMapper.cs +++ b/src/Umbraco.Core/Routing/SiteDomainMapper.cs @@ -34,11 +34,11 @@ namespace Umbraco.Cms.Core.Routing #region Configure private readonly ReaderWriterLockSlim _configLock = new(); - private Dictionary> _qualifiedSites; + private Dictionary>? _qualifiedSites; private bool _disposedValue; - internal Dictionary Sites { get; private set; } - internal Dictionary> Bindings { get; private set; } + internal Dictionary? Sites { get; private set; } + internal Dictionary>? Bindings { get; private set; } // these are for validation //private const string DomainValidationSource = @"^(\*|((?i:http[s]?://)?([-\w]+(\.[-\w]+)*)(:\d+)?(/[-\w]*)?))$"; @@ -196,7 +196,7 @@ namespace Umbraco.Cms.Core.Routing { _configLock.EnterWriteLock(); - foreach (var key in keys.Where(key => !Sites.ContainsKey(key))) + foreach (var key in keys.Where(key => !Sites?.ContainsKey(key) ?? false)) { throw new ArgumentException($"Not an existing site key: {key}.", nameof(keys)); } @@ -235,36 +235,36 @@ namespace Umbraco.Cms.Core.Routing #region Map domains /// - public virtual DomainAndUri MapDomain(IReadOnlyCollection domainAndUris, Uri current, - string culture, string defaultCulture) + public virtual DomainAndUri? MapDomain(IReadOnlyCollection domainAndUris, Uri current, + string? culture, string? defaultCulture) { var currentAuthority = current.GetLeftPart(UriPartial.Authority); - Dictionary qualifiedSites = GetQualifiedSites(current); + Dictionary? qualifiedSites = GetQualifiedSites(current); return MapDomain(domainAndUris, qualifiedSites, currentAuthority, culture, defaultCulture); } /// public virtual IEnumerable MapDomains(IReadOnlyCollection domainAndUris, - Uri current, bool excludeDefault, string culture, string defaultCulture) + Uri current, bool excludeDefault, string? culture, string defaultCulture) { // TODO: ignoring cultures entirely? var currentAuthority = current.GetLeftPart(UriPartial.Authority); - KeyValuePair[] candidateSites = null; + KeyValuePair[]? candidateSites = null; IEnumerable ret = domainAndUris; try { _configLock.EnterReadLock(); - Dictionary qualifiedSites = GetQualifiedSitesInsideLock(current); + Dictionary? qualifiedSites = GetQualifiedSitesInsideLock(current); if (excludeDefault) { // exclude the current one (avoid producing the absolute equivalent of what GetUrl returns) Uri hintWithSlash = current.EndPathWithSlash(); - DomainAndUri hinted = + DomainAndUri? hinted = domainAndUris.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(hintWithSlash)); if (hinted != null) { @@ -277,7 +277,7 @@ namespace Umbraco.Cms.Core.Routing { // it is illegal to call MapDomain if domainAndUris is empty // also, domainAndUris should NOT contain current, hence the test on hinted - DomainAndUri mainDomain = MapDomain(domainAndUris, qualifiedSites, currentAuthority, culture, + DomainAndUri? mainDomain = MapDomain(domainAndUris, qualifiedSites, currentAuthority, culture, defaultCulture); // what GetUrl would get ret = ret.Where(d => d != mainDomain); } @@ -327,7 +327,7 @@ namespace Umbraco.Cms.Core.Routing }); } - private Dictionary GetQualifiedSites(Uri current) + private Dictionary? GetQualifiedSites(Uri current) { try { @@ -344,7 +344,7 @@ namespace Umbraco.Cms.Core.Routing } } - private Dictionary GetQualifiedSitesInsideLock(Uri current) + private Dictionary? GetQualifiedSitesInsideLock(Uri current) { // we do our best, but can't do the impossible if (Sites == null) @@ -376,8 +376,8 @@ namespace Umbraco.Cms.Core.Routing // therefore it is safe to return and exit the configuration lock } - private DomainAndUri MapDomain(IReadOnlyCollection domainAndUris, - Dictionary qualifiedSites, string currentAuthority, string culture, string defaultCulture) + private DomainAndUri? MapDomain(IReadOnlyCollection domainAndUris, + Dictionary? qualifiedSites, string currentAuthority, string? culture, string? defaultCulture) { if (domainAndUris == null) { @@ -402,7 +402,7 @@ namespace Umbraco.Cms.Core.Routing // if current belongs to a site - try to pick the first element // from domainAndUris that also belongs to that site - DomainAndUri ret = currentSite.Equals(default(KeyValuePair)) + DomainAndUri? ret = currentSite.Equals(default(KeyValuePair)) ? null : domainAndUris.FirstOrDefault(d => currentSite.Value.Contains(d.Uri.GetLeftPart(UriPartial.Authority))); diff --git a/src/Umbraco.Core/Routing/UrlInfo.cs b/src/Umbraco.Core/Routing/UrlInfo.cs index aeab881b98..3a5c277725 100644 --- a/src/Umbraco.Core/Routing/UrlInfo.cs +++ b/src/Umbraco.Core/Routing/UrlInfo.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Routing /// /// Initializes a new instance of the class. /// - public UrlInfo(string text, bool isUrl, string culture) + public UrlInfo(string text, bool isUrl, string? culture) { if (string.IsNullOrWhiteSpace(text)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(text)); IsUrl = isUrl; @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core.Routing /// Gets the culture. /// [DataMember(Name = "culture")] - public string Culture { get; } + public string? Culture { get; } /// /// Gets a value indicating whether the URL is a true URL. @@ -58,14 +58,14 @@ namespace Umbraco.Cms.Core.Routing /// /// Compare both culture and Text as invariant strings since URLs are not case sensitive, nor are culture names within Umbraco /// - public bool Equals(UrlInfo other) + public bool Equals(UrlInfo? other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return string.Equals(Culture, other.Culture, StringComparison.InvariantCultureIgnoreCase) && IsUrl == other.IsUrl && string.Equals(Text, other.Text, StringComparison.InvariantCultureIgnoreCase); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/src/Umbraco.Core/Routing/UrlProvider.cs b/src/Umbraco.Core/Routing/UrlProvider.cs index fdf62328a9..adb92d5fe7 100644 --- a/src/Umbraco.Core/Routing/UrlProvider.cs +++ b/src/Umbraco.Core/Routing/UrlProvider.cs @@ -73,7 +73,7 @@ namespace Umbraco.Cms.Core.Routing /// A culture. /// The current absolute URL. /// The URL for the published content. - public string GetUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, Uri current = null) + public string GetUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, Uri? current = null) => GetUrl(GetDocument(id), mode, culture, current); /// @@ -84,7 +84,7 @@ namespace Umbraco.Cms.Core.Routing /// A culture. /// The current absolute URL. /// The URL for the published content. - public string GetUrl(int id, UrlMode mode = UrlMode.Default, string? culture = null, Uri current = null) + public string GetUrl(int id, UrlMode mode = UrlMode.Default, string? culture = null, Uri? current = null) => GetUrl(GetDocument(id), mode, culture, current); /// @@ -101,7 +101,7 @@ namespace Umbraco.Cms.Core.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a URL, it returns "#". /// - public string GetUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, Uri current = null) + public string GetUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, Uri? current = null) { if (content == null || content.ContentType.ItemType == PublishedItemType.Element) return "#"; @@ -126,11 +126,11 @@ namespace Umbraco.Cms.Core.Routing var url = _urlProviders.Select(provider => provider.GetUrl(content, mode, culture, current)) - .FirstOrDefault(u => u != null); + .FirstOrDefault(u => u is not null); return url?.Text ?? "#"; // legacy wants this } - public string GetUrlFromRoute(int id, string route, string culture) + public string GetUrlFromRoute(int id, string? route, string? culture) { var umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext(); var provider = _urlProviders.OfType().FirstOrDefault(); @@ -188,7 +188,7 @@ namespace Umbraco.Cms.Core.Routing /// /// /// - public string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null) + public string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri? current = null) => GetMediaUrl(GetMedia(id), mode, culture, propertyAlias, current); /// @@ -206,7 +206,7 @@ namespace Umbraco.Cms.Core.Routing /// when no culture is specified, the current culture. /// If the provider is unable to provide a URL, it returns . /// - public string GetMediaUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null) + public string GetMediaUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string? culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri? current = null) { if (propertyAlias == null) throw new ArgumentNullException(nameof(propertyAlias)); @@ -235,7 +235,7 @@ namespace Umbraco.Cms.Core.Routing var url = _mediaUrlProviders.Select(provider => provider.GetMediaUrl(content, propertyAlias, mode, culture, current)) - .FirstOrDefault(u => u != null); + .FirstOrDefault(u => u is not null); return url?.Text ?? ""; } diff --git a/src/Umbraco.Core/Routing/UrlProviderExtensions.cs b/src/Umbraco.Core/Routing/UrlProviderExtensions.cs index 3853988aab..07878be7f5 100644 --- a/src/Umbraco.Core/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Core/Routing/UrlProviderExtensions.cs @@ -123,7 +123,7 @@ namespace Umbraco.Extensions if (urlGroup.Key) { - result.AddRange(urlGroup.LegacyDistinctBy(x => x.Text.ToUpperInvariant()) + result.AddRange(urlGroup.LegacyDistinctBy(x => x!.Text.ToUpperInvariant()) .OrderBy(x => x.Text).ThenBy(x => x.Culture)); } else @@ -202,9 +202,9 @@ namespace Umbraco.Extensions // got a URL, deal with collisions, add URL default: // detect collisions, etc - Attempt hasCollision = await DetectCollisionAsync(logger, content, url, culture, + Attempt hasCollision = await DetectCollisionAsync(logger, content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, uriUtility); - if (hasCollision) + if (hasCollision.Success && hasCollision.Result is not null) { result.Add(hasCollision.Result); } @@ -225,7 +225,7 @@ namespace Umbraco.Extensions { // document has a published version yet its URL is "#" => a parent must be // unpublished, walk up the tree until we find it, and report. - IContent parent = content; + IContent? parent = content; do { parent = parent.ParentId > 0 ? contentService.GetParent(parent) : null; @@ -250,7 +250,7 @@ namespace Umbraco.Extensions culture); } - private static async Task> DetectCollisionAsync(ILogger logger, IContent content, string url, + private static async Task> DetectCollisionAsync(ILogger logger, IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, UriUtility uriUtility) @@ -286,28 +286,28 @@ namespace Umbraco.Extensions if (pcr.IgnorePublishedContentCollisions) { - return Attempt.Fail(); + return Attempt.Fail(); } - if (pcr.PublishedContent.Id != content.Id) + if (pcr.PublishedContent?.Id != content.Id) { - IPublishedContent o = pcr.PublishedContent; + IPublishedContent? o = pcr.PublishedContent; var l = new List(); while (o != null) { - l.Add(o.Name(variationContextAccessor)); + l.Add(o.Name(variationContextAccessor)!); o = o.Parent; } l.Reverse(); - var s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent.Id + ")"; + var s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent?.Id + ")"; var urlInfo = UrlInfo.Message(textService.Localize("content", "routeError", new[] { s }), culture); return Attempt.Succeed(urlInfo); } // no collision - return Attempt.Fail(); + return Attempt.Fail(); } } } diff --git a/src/Umbraco.Core/Runtime/MainDom.cs b/src/Umbraco.Core/Runtime/MainDom.cs index ec4e56df1b..cd9f5a7e38 100644 --- a/src/Umbraco.Core/Runtime/MainDom.cs +++ b/src/Umbraco.Core/Runtime/MainDom.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Runtime #region Vars private readonly ILogger _logger; - private IApplicationShutdownRegistry _hostingEnvironment; + private IApplicationShutdownRegistry? _hostingEnvironment; private readonly IMainDomLock _mainDomLock; // our own lock for local consistency @@ -39,8 +39,8 @@ namespace Umbraco.Cms.Core.Runtime private const int LockTimeoutMilliseconds = 40000; // 40 seconds - private Task _listenTask; - private Task _listenCompleteTask; + private Task? _listenTask; + private Task? _listenCompleteTask; #endregion @@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.Runtime { hostingEnvironment.RegisterObject(this); return Acquire(); - }).Value; + })!.Value; } /// @@ -76,7 +76,7 @@ namespace Umbraco.Cms.Core.Runtime /// A value indicating whether it was possible to register. /// If registering is successful, then the action /// is guaranteed to execute before the AppDomain releases the main domain status. - public bool Register(Action install = null, Action release = null, int weight = 100) + public bool Register(Action? install = null, Action? release = null, int weight = 100) { lock (_locko) { diff --git a/src/Umbraco.Core/Runtime/MainDomSemaphoreLock.cs b/src/Umbraco.Core/Runtime/MainDomSemaphoreLock.cs index 905bfe7f25..cd205a0542 100644 --- a/src/Umbraco.Core/Runtime/MainDomSemaphoreLock.cs +++ b/src/Umbraco.Core/Runtime/MainDomSemaphoreLock.cs @@ -18,7 +18,7 @@ namespace Umbraco.Cms.Core.Runtime // release the lock because a new domain wants to be the main domain private readonly EventWaitHandle _signal; private readonly ILogger _logger; - private IDisposable _lockRelease; + private IDisposable? _lockRelease; public MainDomSemaphoreLock(ILogger logger, IHostingEnvironment hostingEnvironment) { diff --git a/src/Umbraco.Core/Security/AuthenticationExtensions.cs b/src/Umbraco.Core/Security/AuthenticationExtensions.cs index 3068b1c41d..187d44b05d 100644 --- a/src/Umbraco.Core/Security/AuthenticationExtensions.cs +++ b/src/Umbraco.Core/Security/AuthenticationExtensions.cs @@ -22,11 +22,11 @@ namespace Umbraco.Extensions } } - public static CultureInfo GetCulture(this IIdentity identity) + public static CultureInfo? GetCulture(this IIdentity identity) { - if (identity is ClaimsIdentity umbIdentity && umbIdentity.VerifyBackOfficeIdentity(out _) && umbIdentity.IsAuthenticated) + if (identity is ClaimsIdentity umbIdentity && umbIdentity.VerifyBackOfficeIdentity(out _) && umbIdentity.IsAuthenticated && umbIdentity.GetCultureString() is not null) { - return CultureInfo.GetCultureInfo(umbIdentity.GetCultureString()); + return CultureInfo.GetCultureInfo(umbIdentity.GetCultureString()!); } return null; diff --git a/src/Umbraco.Core/Security/BackOfficeExternalLoginProviderErrors.cs b/src/Umbraco.Core/Security/BackOfficeExternalLoginProviderErrors.cs index f0ce1f3f5d..42903d2b64 100644 --- a/src/Umbraco.Core/Security/BackOfficeExternalLoginProviderErrors.cs +++ b/src/Umbraco.Core/Security/BackOfficeExternalLoginProviderErrors.cs @@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.Security Errors = errors ?? Enumerable.Empty(); } - public string AuthenticationType { get; set; } - public IEnumerable Errors { get; set; } + public string? AuthenticationType { get; set; } + public IEnumerable? Errors { get; set; } } } diff --git a/src/Umbraco.Core/Security/ClaimsPrincipalExtensions.cs b/src/Umbraco.Core/Security/ClaimsPrincipalExtensions.cs index 1ee5699868..b9912a3911 100644 --- a/src/Umbraco.Core/Security/ClaimsPrincipalExtensions.cs +++ b/src/Umbraco.Core/Security/ClaimsPrincipalExtensions.cs @@ -27,7 +27,7 @@ namespace Umbraco.Extensions /// /// /// - public static ClaimsIdentity GetUmbracoIdentity(this IPrincipal principal) + public static ClaimsIdentity? GetUmbracoIdentity(this IPrincipal principal) { //If it's already a UmbracoBackOfficeIdentity if (principal.Identity is ClaimsIdentity claimsIdentity @@ -41,10 +41,14 @@ namespace Umbraco.Extensions // We can have assigned more identities if it is a preview request. if (principal is ClaimsPrincipal claimsPrincipal ) { - claimsIdentity = claimsPrincipal.Identities.FirstOrDefault(x=>x.IsBackOfficeAuthenticationType()); - if (claimsIdentity.VerifyBackOfficeIdentity(out backOfficeIdentity)) + var identity = claimsPrincipal.Identities.FirstOrDefault(x => x.IsBackOfficeAuthenticationType()); + if (identity is not null) { - return backOfficeIdentity; + claimsIdentity = identity; + if (claimsIdentity.VerifyBackOfficeIdentity(out backOfficeIdentity)) + { + return backOfficeIdentity; + } } } @@ -78,7 +82,7 @@ namespace Umbraco.Extensions var ticketExpires = claimsPrincipal.FindFirst(Constants.Security.TicketExpiresClaimType)?.Value; if (ticketExpires.IsNullOrWhiteSpace()) return 0; - var utcExpired = DateTimeOffset.Parse(ticketExpires, null, DateTimeStyles.RoundtripKind); + var utcExpired = DateTimeOffset.Parse(ticketExpires!, null, DateTimeStyles.RoundtripKind); var secondsRemaining = utcExpired.Subtract(now).TotalSeconds; return secondsRemaining; diff --git a/src/Umbraco.Core/Security/ContentPermissions.cs b/src/Umbraco.Core/Security/ContentPermissions.cs index 273fb40377..a0bcb64ced 100644 --- a/src/Umbraco.Core/Security/ContentPermissions.cs +++ b/src/Umbraco.Core/Security/ContentPermissions.cs @@ -109,8 +109,8 @@ namespace Umbraco.Cms.Core.Security public ContentAccess CheckPermissions( int nodeId, IUser user, - out IUmbracoEntity entity, - IReadOnlyList permissionsToCheck = null) + out IUmbracoEntity? entity, + IReadOnlyList? permissionsToCheck = null) { if (user == null) throw new ArgumentNullException(nameof(user)); @@ -160,8 +160,8 @@ namespace Umbraco.Cms.Core.Security public ContentAccess CheckPermissions( int nodeId, IUser user, - out IContent contentItem, - IReadOnlyList permissionsToCheck = null) + out IContent? contentItem, + IReadOnlyList? permissionsToCheck = null) { if (user == null) throw new ArgumentNullException(nameof(user)); @@ -197,7 +197,7 @@ namespace Umbraco.Cms.Core.Security : ContentAccess.Denied; } - private bool CheckPermissionsPath(string? path, IUser user, IReadOnlyList permissionsToCheck = null) + private bool CheckPermissionsPath(string? path, IUser user, IReadOnlyList? permissionsToCheck = null) { if (permissionsToCheck == null) { diff --git a/src/Umbraco.Core/Security/ExternalLogin.cs b/src/Umbraco.Core/Security/ExternalLogin.cs index 48bbfa2091..631fe52b28 100644 --- a/src/Umbraco.Core/Security/ExternalLogin.cs +++ b/src/Umbraco.Core/Security/ExternalLogin.cs @@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.Security /// /// Initializes a new instance of the class. /// - public ExternalLogin(string loginProvider, string providerKey, string userData = null) + public ExternalLogin(string loginProvider, string providerKey, string? userData = null) { LoginProvider = loginProvider ?? throw new ArgumentNullException(nameof(loginProvider)); ProviderKey = providerKey ?? throw new ArgumentNullException(nameof(providerKey)); @@ -23,6 +23,6 @@ namespace Umbraco.Cms.Core.Security public string ProviderKey { get; } /// - public string UserData { get; } + public string? UserData { get; } } } diff --git a/src/Umbraco.Core/Security/IExternalLogin.cs b/src/Umbraco.Core/Security/IExternalLogin.cs index b285bd35eb..0c09cecfc0 100644 --- a/src/Umbraco.Core/Security/IExternalLogin.cs +++ b/src/Umbraco.Core/Security/IExternalLogin.cs @@ -18,6 +18,6 @@ namespace Umbraco.Cms.Core.Security /// /// Gets the user data /// - string UserData { get; } + string? UserData { get; } } } diff --git a/src/Umbraco.Core/Security/IIdentityUserLogin.cs b/src/Umbraco.Core/Security/IIdentityUserLogin.cs index 67ca739509..c2ce78e7f5 100644 --- a/src/Umbraco.Core/Security/IIdentityUserLogin.cs +++ b/src/Umbraco.Core/Security/IIdentityUserLogin.cs @@ -26,6 +26,6 @@ namespace Umbraco.Cms.Core.Security /// /// Gets or sets any arbitrary data for the user and external provider /// - string UserData { get; set; } + string? UserData { get; set; } } } diff --git a/src/Umbraco.Core/Security/IdentityUserLogin.cs b/src/Umbraco.Core/Security/IdentityUserLogin.cs index 4775b9d3e6..402660ead9 100644 --- a/src/Umbraco.Core/Security/IdentityUserLogin.cs +++ b/src/Umbraco.Core/Security/IdentityUserLogin.cs @@ -41,6 +41,6 @@ namespace Umbraco.Cms.Core.Security public string UserId { get; set; } /// - public string UserData { get; set; } + public string? UserData { get; set; } } } diff --git a/src/Umbraco.Core/Security/MediaPermissions.cs b/src/Umbraco.Core/Security/MediaPermissions.cs index 724049d6b9..99b4d15cd6 100644 --- a/src/Umbraco.Core/Security/MediaPermissions.cs +++ b/src/Umbraco.Core/Security/MediaPermissions.cs @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Security /// /// The content to lookup, if the contentItem is not specified /// - public MediaAccess CheckPermissions(IUser user, int nodeId, out IMedia media) + public MediaAccess CheckPermissions(IUser user, int nodeId, out IMedia? media) { if (user == null) throw new ArgumentNullException(nameof(user)); diff --git a/src/Umbraco.Core/Security/UpdateMemberProfileResult.cs b/src/Umbraco.Core/Security/UpdateMemberProfileResult.cs index 90c14086b5..b6b6c241e4 100644 --- a/src/Umbraco.Core/Security/UpdateMemberProfileResult.cs +++ b/src/Umbraco.Core/Security/UpdateMemberProfileResult.cs @@ -8,7 +8,7 @@ public UpdateMemberProfileStatus Status { get; private set; } - public string ErrorMessage { get; private set; } + public string? ErrorMessage { get; private set; } public static UpdateMemberProfileResult Success() { diff --git a/src/Umbraco.Core/Semver/Semver.cs b/src/Umbraco.Core/Semver/Semver.cs index f1fd48806e..5a04553f1b 100644 --- a/src/Umbraco.Core/Semver/Semver.cs +++ b/src/Umbraco.Core/Semver/Semver.cs @@ -62,7 +62,7 @@ namespace Umbraco.Cms.Core.Semver private SemVersion(SerializationInfo info, StreamingContext context) { if (info == null) throw new ArgumentNullException("info"); - var semVersion = Parse(info.GetString("SemVersion")); + var semVersion = Parse(info.GetString("SemVersion")!); Major = semVersion.Major; Minor = semVersion.Minor; Patch = semVersion.Patch; @@ -183,7 +183,7 @@ namespace Umbraco.Cms.Core.Semver /// version string was not valid. /// If set to true minor and patch version are required, else they default to 0. /// False when a invalid version string is passed, otherwise true. - public static bool TryParse(string version, out SemVersion semver, bool strict = false) + public static bool TryParse(string version, out SemVersion? semver, bool strict = false) { try { @@ -234,7 +234,7 @@ namespace Umbraco.Cms.Core.Semver /// The build text. /// The new version object. public SemVersion Change(int? major = null, int? minor = null, int? patch = null, - string prerelease = null, string build = null) + string? prerelease = null, string? build = null) { return new SemVersion( major ?? this.Major, @@ -313,9 +313,9 @@ namespace Umbraco.Cms.Core.Semver /// Zero This instance occurs in the same position in the sort order as . i /// Greater than zero This instance follows in the sort order. /// - public int CompareTo(object obj) + public int CompareTo(object? obj) { - return CompareTo((SemVersion)obj); + return CompareTo((SemVersion?)obj); } /// @@ -331,7 +331,7 @@ namespace Umbraco.Cms.Core.Semver /// Zero This instance occurs in the same position in the sort order as . i /// Greater than zero This instance follows in the sort order. /// - public int CompareTo(SemVersion other) + public int CompareTo(SemVersion? other) { if (ReferenceEquals(other, null)) return 1; @@ -434,7 +434,7 @@ namespace Umbraco.Cms.Core.Semver /// /// true if the specified is equal to this instance; otherwise, false. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(obj, null)) return false; diff --git a/src/Umbraco.Core/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs index 89b70ed00f..fae700f3a7 100644 --- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs @@ -59,7 +59,7 @@ namespace Umbraco.Extensions foreach (var udi in ids) { var guidUdi = udi as GuidUdi; - if (guidUdi == null) + if (guidUdi is null) throw new InvalidOperationException("The UDI provided isn't of type " + typeof(GuidUdi) + " which is required by content"); guids.Add(guidUdi); } @@ -79,7 +79,7 @@ namespace Umbraco.Extensions public static IContent CreateContent(this IContentService contentService, string name, Udi parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { var guidUdi = parentId as GuidUdi; - if (guidUdi == null) + if (guidUdi is null) throw new InvalidOperationException("The UDI provided isn't of type " + typeof(GuidUdi) + " which is required by content"); var parent = contentService.GetById(guidUdi.Guid); return contentService.Create(name, parent, contentTypeAlias, userId); diff --git a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs index 654861fad5..cd3c5273a1 100644 --- a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs @@ -82,7 +82,7 @@ namespace Umbraco.Extensions // if it is not used then composition is possible // hashset guarantees uniqueness on Id var list = new HashSet(new DelegateEqualityComparer( - (x, y) => x.Id == y.Id, + (x, y) => x?.Id == y?.Id, x => x.Id)); // usable types are those that are top-level @@ -134,7 +134,7 @@ namespace Umbraco.Extensions } - private static IContentTypeComposition[] GetAncestors(IContentTypeComposition ctype, IContentTypeComposition[] allContentTypes) + private static IContentTypeComposition[] GetAncestors(IContentTypeComposition? ctype, IContentTypeComposition[] allContentTypes) { if (ctype == null) return new IContentTypeComposition[] {}; var ancestors = new List(); @@ -160,13 +160,13 @@ namespace Umbraco.Extensions /// /// /// - private static IEnumerable GetDirectOrIndirect(IContentTypeComposition ctype) + private static IEnumerable GetDirectOrIndirect(IContentTypeComposition? ctype) { if (ctype == null) return Enumerable.Empty(); // hashset guarantees uniqueness on Id var all = new HashSet(new DelegateEqualityComparer( - (x, y) => x.Id == y.Id, + (x, y) => x?.Id == y?.Id, x => x.Id)); var stack = new Stack(); diff --git a/src/Umbraco.Core/Services/DashboardService.cs b/src/Umbraco.Core/Services/DashboardService.cs index d4116f5dd8..a495c87454 100644 --- a/src/Umbraco.Core/Services/DashboardService.cs +++ b/src/Umbraco.Core/Services/DashboardService.cs @@ -39,7 +39,7 @@ namespace Umbraco.Cms.Core.Services if (!CheckUserAccessByRules(currentUser, _sectionService, dashboard.AccessRules)) continue; - if (dashboard.View.InvariantEndsWith(".ascx")) + if (dashboard.View?.InvariantEndsWith(".ascx") ?? false) throw new NotSupportedException("Legacy UserControl (.ascx) dashboards are no longer supported."); var dashboards = new List { dashboard }; @@ -69,7 +69,7 @@ namespace Umbraco.Cms.Core.Services var (denyRules, grantRules, grantBySectionRules) = GroupRules(rules); var hasAccess = true; - string[] assignedUserGroups = null; + string[]? assignedUserGroups = null; // if there are no grant rules, then access is granted by default, unless denied // otherwise, grant rules determine if access can be granted at all @@ -117,7 +117,7 @@ namespace Umbraco.Cms.Core.Services private static (IAccessRule[], IAccessRule[], IAccessRule[]) GroupRules(IEnumerable rules) { - IAccessRule[] denyRules = null, grantRules = null, grantBySectionRules = null; + IAccessRule[]? denyRules = null, grantRules = null, grantBySectionRules = null; var groupedRules = rules.GroupBy(x => x.Type); foreach (var group in groupedRules) diff --git a/src/Umbraco.Core/Services/IAuditService.cs b/src/Umbraco.Core/Services/IAuditService.cs index bae50f55c8..63beceef1b 100644 --- a/src/Umbraco.Core/Services/IAuditService.cs +++ b/src/Umbraco.Core/Services/IAuditService.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.Services /// public interface IAuditService : IService { - void Add(AuditType type, int userId, int objectId, string entityType, string comment, string parameters = null); + void Add(AuditType type, int userId, int objectId, string entityType, string comment, string? parameters = null); IEnumerable GetLogs(int objectId); IEnumerable GetUserLogs(int userId, AuditType type, DateTime? sinceDate = null); @@ -37,8 +37,8 @@ namespace Umbraco.Cms.Core.Services /// IEnumerable GetPagedItemsByEntity(int entityId, long pageIndex, int pageSize, out long totalRecords, Direction orderDirection = Direction.Descending, - AuditType[] auditTypeFilter = null, - IQuery customFilter = null); + AuditType[]? auditTypeFilter = null, + IQuery? customFilter = null); /// /// Returns paged items in the audit trail for a given user @@ -60,8 +60,8 @@ namespace Umbraco.Cms.Core.Services /// IEnumerable GetPagedItemsByUser(int userId, long pageIndex, int pageSize, out long totalRecords, Direction orderDirection = Direction.Descending, - AuditType[] auditTypeFilter = null, - IQuery customFilter = null); + AuditType[]? auditTypeFilter = null, + IQuery? customFilter = null); /// /// Writes an audit entry for an audited event. diff --git a/src/Umbraco.Core/Services/IConsentService.cs b/src/Umbraco.Core/Services/IConsentService.cs index a8e7e6cd8b..1833090501 100644 --- a/src/Umbraco.Core/Services/IConsentService.cs +++ b/src/Umbraco.Core/Services/IConsentService.cs @@ -25,7 +25,7 @@ namespace Umbraco.Cms.Core.Services /// The state of the consent. /// Additional free text. /// The corresponding consent entity. - IConsent RegisterConsent(string source, string context, string action, ConsentState state, string comment = null); + IConsent RegisterConsent(string source, string context, string action, ConsentState state, string? comment = null); /// /// Retrieves consents. @@ -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 28b1eb8636..fb9fd511fe 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -168,7 +168,7 @@ namespace Umbraco.Cms.Core.Services /// Gets documents in the recycle bin. /// IEnumerable GetPagedContentInRecycleBin(long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets child documents of a parent. @@ -180,7 +180,7 @@ namespace Umbraco.Cms.Core.Services /// Query filter. /// Ordering infos. IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets descendant documents of a given parent. @@ -192,7 +192,7 @@ namespace Umbraco.Cms.Core.Services /// Query filter. /// Ordering infos. IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets paged documents of a content @@ -204,7 +204,7 @@ namespace Umbraco.Cms.Core.Services /// Search text filter. /// Ordering infos. IEnumerable GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords, - IQuery filter, Ordering ordering = null); + IQuery filter, Ordering? ordering = null); /// /// Gets paged documents for specified content types @@ -216,27 +216,27 @@ namespace Umbraco.Cms.Core.Services /// Search text filter. /// Ordering infos. IEnumerable GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords, - IQuery filter, Ordering ordering = null); + IQuery filter, Ordering? ordering = null); /// /// Counts documents of a given document type. /// - int Count(string documentTypeAlias = null); + int Count(string? documentTypeAlias = null); /// /// Counts published documents of a given document type. /// - int CountPublished(string documentTypeAlias = null); + int CountPublished(string? documentTypeAlias = null); /// /// Counts child documents of a given parent, of a given document type. /// - int CountChildren(int parentId, string documentTypeAlias = null); + int CountChildren(int parentId, string? documentTypeAlias = null); /// /// Counts descendant documents of a given parent, of a given document type. /// - int CountDescendants(int parentId, string documentTypeAlias = null); + int CountDescendants(int parentId, string? documentTypeAlias = null); /// /// Gets a value indicating whether a document has children. @@ -250,7 +250,7 @@ namespace Umbraco.Cms.Core.Services /// /// Saves a document. /// - OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, ContentScheduleCollection contentSchedule = null); + OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, ContentScheduleCollection? contentSchedule = null); /// /// Saves documents. diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 727851ef02..a9e47e28b0 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -39,7 +39,7 @@ namespace Umbraco.Cms.Core.Services /// /// Id of the /// - IDataType GetDataType(int id); + IDataType GetDataType(int? id); /// /// Gets a by its unique guid Id diff --git a/src/Umbraco.Core/Services/IEntityService.cs b/src/Umbraco.Core/Services/IEntityService.cs index ff4b2cd301..a5bc143fcf 100644 --- a/src/Umbraco.Core/Services/IEntityService.cs +++ b/src/Umbraco.Core/Services/IEntityService.cs @@ -175,26 +175,26 @@ namespace Umbraco.Cms.Core.Services /// Gets children of an entity. /// IEnumerable GetPagedChildren(int id, UmbracoObjectTypes objectType, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets descendants of an entity. /// IEnumerable GetPagedDescendants(int id, UmbracoObjectTypes objectType, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets descendants of entities. /// IEnumerable GetPagedDescendants(IEnumerable ids, UmbracoObjectTypes objectType, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); // TODO: Do we really need this? why not just pass in -1 /// /// Gets descendants of root. /// IEnumerable GetPagedDescendants(UmbracoObjectTypes objectType, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null, bool includeTrashed = true); + IQuery? filter = null, Ordering? ordering = null, bool includeTrashed = true); /// /// Gets the object type of an entity. diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index fcf5f2b2f3..4a989b8ba5 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -24,8 +24,8 @@ namespace Umbraco.Cms.Core.Services IPartialView GetPartialView(string path); IPartialView GetPartialViewMacro(string path); - Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); - Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); + Attempt CreatePartialView(IPartialView partialView, string? snippetName = null, int userId = Constants.Security.SuperUserId); + Attempt CreatePartialViewMacro(IPartialView partialView, string? snippetName = null, int userId = Constants.Security.SuperUserId); bool DeletePartialView(string path, int userId = Constants.Security.SuperUserId); bool DeletePartialViewMacro(string path, int userId = Constants.Security.SuperUserId); Attempt SavePartialView(IPartialView partialView, int userId = Constants.Security.SuperUserId); @@ -253,7 +253,7 @@ namespace Umbraco.Cms.Core.Services /// Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId); - ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = Constants.Security.SuperUserId); + ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate? masterTemplate = null, int userId = Constants.Security.SuperUserId); /// /// Deletes a template by its alias diff --git a/src/Umbraco.Core/Services/ILocalizationService.cs b/src/Umbraco.Core/Services/ILocalizationService.cs index cd28e4f5b3..e880602c3b 100644 --- a/src/Umbraco.Core/Services/ILocalizationService.cs +++ b/src/Umbraco.Core/Services/ILocalizationService.cs @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.Services /// /// /// - IDictionaryItem CreateDictionaryItemWithIdentity(string key, Guid? parentId, string defaultValue = null); + IDictionaryItem CreateDictionaryItemWithIdentity(string key, Guid? parentId, string? defaultValue = null); /// /// Gets a by its id diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 19b509134e..8f40866eb3 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -11,10 +11,10 @@ namespace Umbraco.Cms.Core.Services /// public interface IMediaService : IContentServiceBase { - int CountNotTrashed(string contentTypeAlias = null); - int Count(string mediaTypeAlias = null); - int CountChildren(int parentId, string mediaTypeAlias = null); - int CountDescendants(int parentId, string mediaTypeAlias = null); + int CountNotTrashed(string? contentTypeAlias = null); + int Count(string? mediaTypeAlias = null); + int CountChildren(int parentId, string? mediaTypeAlias = null); + int CountDescendants(int parentId, string? mediaTypeAlias = null); IEnumerable GetByIds(IEnumerable ids); IEnumerable GetByIds(IEnumerable ids); @@ -87,7 +87,7 @@ namespace Umbraco.Cms.Core.Services /// /// An Enumerable list of objects IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets a collection of objects by Parent Id @@ -100,7 +100,7 @@ namespace Umbraco.Cms.Core.Services /// /// An Enumerable list of objects IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets paged documents of a content @@ -112,7 +112,7 @@ namespace Umbraco.Cms.Core.Services /// Search text filter. /// Ordering infos. IEnumerable GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets paged documents for specified content types @@ -124,7 +124,7 @@ namespace Umbraco.Cms.Core.Services /// Search text filter. /// Ordering infos. IEnumerable GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Gets a collection of objects, which reside at the first level / root @@ -137,7 +137,7 @@ namespace Umbraco.Cms.Core.Services /// /// An Enumerable list of objects IEnumerable GetPagedMediaInRecycleBin(long pageIndex, int pageSize, out long totalRecords, - IQuery filter = null, Ordering ordering = null); + IQuery? filter = null, Ordering? ordering = null); /// /// Moves an object to a new location diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index 3220cf9fd9..6619462779 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core.Services /// Search text filter /// IEnumerable GetAll(long pageIndex, int pageSize, out long totalRecords, - string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = ""); + string orderBy, Direction orderDirection, string? memberTypeAlias = null, string filter = ""); /// /// Gets a list of paged objects @@ -97,7 +97,7 @@ namespace Umbraco.Cms.Core.Services /// If no alias is supplied then the count for all Member will be returned /// Optional alias for the MemberType when counting number of Members /// with number of Members - int Count(string memberTypeAlias = null); + int Count(string? memberTypeAlias = null); /// /// Checks if a Member with the id exists diff --git a/src/Umbraco.Core/Services/IRedirectUrlService.cs b/src/Umbraco.Core/Services/IRedirectUrlService.cs index d97bf8cec4..4d8769cf6b 100644 --- a/src/Umbraco.Core/Services/IRedirectUrlService.cs +++ b/src/Umbraco.Core/Services/IRedirectUrlService.cs @@ -54,7 +54,7 @@ namespace Umbraco.Cms.Core.Services /// The Umbraco redirect URL route. /// The culture of the request. /// The most recent redirect URLs corresponding to the route. - IRedirectUrl GetMostRecentRedirectUrl(string url, string culture); + IRedirectUrl GetMostRecentRedirectUrl(string url, string? culture); /// /// Gets all redirect URLs for a content item. diff --git a/src/Umbraco.Core/Services/IRelationService.cs b/src/Umbraco.Core/Services/IRelationService.cs index ce00f774f8..b1381e2319 100644 --- a/src/Umbraco.Core/Services/IRelationService.cs +++ b/src/Umbraco.Core/Services/IRelationService.cs @@ -171,7 +171,7 @@ namespace Umbraco.Cms.Core.Services /// /// /// - IEnumerable GetPagedByRelationTypeId(int relationTypeId, long pageIndex, int pageSize, out long totalRecords, Ordering ordering = null); + IEnumerable GetPagedByRelationTypeId(int relationTypeId, long pageIndex, int pageSize, out long totalRecords, Ordering? ordering = null); /// /// Gets the Child object from a Relation as an diff --git a/src/Umbraco.Core/Services/IRuntimeState.cs b/src/Umbraco.Core/Services/IRuntimeState.cs index 9e494a7385..2b72149042 100644 --- a/src/Umbraco.Core/Services/IRuntimeState.cs +++ b/src/Umbraco.Core/Services/IRuntimeState.cs @@ -55,7 +55,7 @@ namespace Umbraco.Cms.Core.Services /// void DetermineRuntimeLevel(); - void Configure(RuntimeLevel level, RuntimeLevelReason reason, Exception bootFailedException = null); + void Configure(RuntimeLevel level, RuntimeLevelReason reason, Exception? bootFailedException = null); /// /// Returns any state data that was collected during startup diff --git a/src/Umbraco.Core/Services/ISectionService.cs b/src/Umbraco.Core/Services/ISectionService.cs index 94aa267dab..ded733963b 100644 --- a/src/Umbraco.Core/Services/ISectionService.cs +++ b/src/Umbraco.Core/Services/ISectionService.cs @@ -22,6 +22,6 @@ namespace Umbraco.Cms.Core.Services /// /// The application alias. /// - ISection GetByAlias(string appAlias); + ISection? GetByAlias(string appAlias); } } diff --git a/src/Umbraco.Core/Services/ITagService.cs b/src/Umbraco.Core/Services/ITagService.cs index 0ec356eea7..c5647b02d2 100644 --- a/src/Umbraco.Core/Services/ITagService.cs +++ b/src/Umbraco.Core/Services/ITagService.cs @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.Services /// /// Gets all documents tagged with the specified tag. /// - IEnumerable GetTaggedContentByTag(string tag, string group = null, string? culture = null); + IEnumerable GetTaggedContentByTag(string tag, string? group = null, string? culture = null); /// /// Gets all media tagged with any tag in the specified group. @@ -43,7 +43,7 @@ namespace Umbraco.Cms.Core.Services /// /// Gets all media tagged with the specified tag. /// - IEnumerable GetTaggedMediaByTag(string tag, string group = null, string? culture = null); + IEnumerable GetTaggedMediaByTag(string tag, string? group = null, string? culture = null); /// /// Gets all members tagged with any tag in the specified group. @@ -53,46 +53,46 @@ namespace Umbraco.Cms.Core.Services /// /// Gets all members tagged with the specified tag. /// - IEnumerable GetTaggedMembersByTag(string tag, string group = null, string? culture = null); + IEnumerable GetTaggedMembersByTag(string tag, string? group = null, string? culture = null); /// /// Gets all tags. /// - IEnumerable GetAllTags(string group = null, string? culture = null); + IEnumerable GetAllTags(string? group = null, string? culture = null); /// /// Gets all document tags. /// - IEnumerable GetAllContentTags(string group = null, string? culture = null); + IEnumerable GetAllContentTags(string? group = null, string? culture = null); /// /// Gets all media tags. /// - IEnumerable GetAllMediaTags(string group = null, string? culture = null); + IEnumerable GetAllMediaTags(string? group = null, string? culture = null); /// /// Gets all member tags. /// - IEnumerable GetAllMemberTags(string group = null, string? culture = null); + IEnumerable GetAllMemberTags(string? group = null, string? culture = null); /// /// Gets all tags attached to an entity via a property. /// - IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string group = null, string? culture = null); + IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string? group = null, string? culture = null); /// /// Gets all tags attached to an entity. /// - IEnumerable GetTagsForEntity(int contentId, string group = null, string? culture = null); + IEnumerable GetTagsForEntity(int contentId, string? group = null, string? culture = null); /// /// Gets all tags attached to an entity via a property. /// - IEnumerable GetTagsForProperty(Guid contentId, string propertyTypeAlias, string group = null, string? culture = null); + IEnumerable GetTagsForProperty(Guid contentId, string propertyTypeAlias, string? group = null, string? culture = null); /// /// Gets all tags attached to an entity. /// - IEnumerable GetTagsForEntity(Guid contentId, string group = null, string? culture = null); + IEnumerable GetTagsForEntity(Guid contentId, string? group = null, string? culture = null); } } diff --git a/src/Umbraco.Core/Services/ITreeService.cs b/src/Umbraco.Core/Services/ITreeService.cs index 362eab4594..b67e36e15b 100644 --- a/src/Umbraco.Core/Services/ITreeService.cs +++ b/src/Umbraco.Core/Services/ITreeService.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.Services /// Gets a tree. /// /// The tree alias. - Tree GetByAlias(string treeAlias); + Tree? GetByAlias(string treeAlias); /// /// Gets all trees. diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs index 2e1c0ffca3..2c9b2eb938 100644 --- a/src/Umbraco.Core/Services/IUserService.cs +++ b/src/Umbraco.Core/Services/IUserService.cs @@ -62,10 +62,10 @@ namespace Umbraco.Cms.Core.Services /// IEnumerable GetAll(long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, - UserState[] userState = null, - string[] includeUserGroups = null, - string[] excludeUserGroups = null, - IQuery filter = null); + UserState[]? userState = null, + string[]? includeUserGroups = null, + string[]? excludeUserGroups = null, + IQuery? filter = null); /// /// Get paged users @@ -83,9 +83,9 @@ namespace Umbraco.Cms.Core.Services /// IEnumerable GetAll(long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, - UserState[] userState = null, - string[] userGroups = null, - string filter = null); + UserState[]? userState = null, + string[]? userGroups = null, + string? filter = null); /// /// Deletes or disables a User @@ -179,7 +179,7 @@ namespace Umbraco.Cms.Core.Services /// /// Specify the nodes to replace permissions for. If nothing is specified all permissions are removed. /// If no 'entityIds' are specified all permissions will be removed for the specified group. - void ReplaceUserGroupPermissions(int groupId, IEnumerable permissions, params int[] entityIds); + void ReplaceUserGroupPermissions(int groupId, IEnumerable? permissions, params int[] entityIds); /// /// Assigns the same permission set for a single user group to any number of entities @@ -243,7 +243,7 @@ namespace Umbraco.Cms.Core.Services /// If null than no changes are made to the users who are assigned to this group, however if a value is passed in /// than all users will be removed from this group and only these users will be added /// - void Save(IUserGroup userGroup, int[] userIds = null); + void Save(IUserGroup userGroup, int[]? userIds = null); /// /// Deletes a UserGroup diff --git a/src/Umbraco.Core/Services/MediaServiceExtensions.cs b/src/Umbraco.Core/Services/MediaServiceExtensions.cs index ef0dfa5f97..1cf648c35d 100644 --- a/src/Umbraco.Core/Services/MediaServiceExtensions.cs +++ b/src/Umbraco.Core/Services/MediaServiceExtensions.cs @@ -25,7 +25,7 @@ namespace Umbraco.Extensions foreach (var udi in ids) { var guidUdi = udi as GuidUdi; - if (guidUdi == null) + if (guidUdi is null) throw new InvalidOperationException("The UDI provided isn't of type " + typeof(GuidUdi) + " which is required by media"); guids.Add(guidUdi); } @@ -36,7 +36,7 @@ namespace Umbraco.Extensions public static IMedia CreateMedia(this IMediaService mediaService, string name, Udi parentId, string mediaTypeAlias, int userId = 0) { var guidUdi = parentId as GuidUdi; - if (guidUdi == null) + if (guidUdi is null) throw new InvalidOperationException("The UDI provided isn't of type " + typeof(GuidUdi) + " which is required by media"); var parent = mediaService.GetById(guidUdi.Guid); return mediaService.CreateMedia(name, parent, mediaTypeAlias, userId); diff --git a/src/Umbraco.Core/Services/OperationResult.cs b/src/Umbraco.Core/Services/OperationResult.cs index f00c6b5d30..43985fdde2 100644 --- a/src/Umbraco.Core/Services/OperationResult.cs +++ b/src/Umbraco.Core/Services/OperationResult.cs @@ -89,7 +89,7 @@ namespace Umbraco.Cms.Core.Services /// /// Gets the entity. /// - public TEntity Entity { get; } + public TEntity? Entity { get; } } /// @@ -127,28 +127,28 @@ namespace Umbraco.Cms.Core.Services /// /// The event messages produced by the operation. /// A new attempt instance. - public static Attempt Succeed(EventMessages eventMessages) + public static Attempt Succeed(EventMessages eventMessages) { return Core.Attempt.Succeed(new OperationResult(OperationResultType.Success, eventMessages)); } - public static Attempt> Succeed(EventMessages eventMessages) + public static Attempt?> Succeed(EventMessages eventMessages) { return Core.Attempt.Succeed(new OperationResult(OperationResultType.Success, eventMessages)); } - public static Attempt> Succeed(EventMessages eventMessages, TValue value) + public static Attempt?> Succeed(EventMessages eventMessages, TValue value) { return Core.Attempt.Succeed(new OperationResult(OperationResultType.Success, eventMessages, value)); } - public static Attempt> Succeed(TStatusType statusType, EventMessages eventMessages) + public static Attempt?> Succeed(TStatusType statusType, EventMessages eventMessages) where TStatusType : struct { return Core.Attempt.Succeed(new OperationResult(statusType, eventMessages)); } - public static Attempt> Succeed(TStatusType statusType, EventMessages eventMessages, TValue value) + public static Attempt?> Succeed(TStatusType statusType, EventMessages eventMessages, TValue value) where TStatusType : struct { return Core.Attempt.Succeed(new OperationResult(statusType, eventMessages, value)); @@ -159,7 +159,7 @@ namespace Umbraco.Cms.Core.Services /// /// The event messages produced by the operation. /// A new attempt instance. - public static Attempt NoOperation(EventMessages eventMessages) + public static Attempt NoOperation(EventMessages eventMessages) { return Core.Attempt.Succeed(new OperationResult(OperationResultType.NoOperation, eventMessages)); } @@ -169,17 +169,17 @@ namespace Umbraco.Cms.Core.Services /// /// The event messages produced by the operation. /// A new attempt instance. - public static Attempt Cancel(EventMessages eventMessages) + public static Attempt Cancel(EventMessages eventMessages) { return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages)); } - public static Attempt> Cancel(EventMessages eventMessages) + public static Attempt?> Cancel(EventMessages eventMessages) { return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages)); } - public static Attempt> Cancel(EventMessages eventMessages, TValue value) + public static Attempt?> Cancel(EventMessages eventMessages, TValue value) { return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages, value)); } @@ -201,7 +201,7 @@ namespace Umbraco.Cms.Core.Services return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedExceptionThrown, eventMessages), exception); } - public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages) + public static Attempt?> Fail(TStatusType statusType, EventMessages eventMessages) where TStatusType : struct { return Core.Attempt.Fail(new OperationResult(statusType, eventMessages)); @@ -213,13 +213,13 @@ namespace Umbraco.Cms.Core.Services return Core.Attempt.Fail(new OperationResult(statusType, eventMessages), exception); } - public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages) + public static Attempt?> Fail(TStatusType statusType, EventMessages eventMessages) where TStatusType : struct { return Core.Attempt.Fail(new OperationResult(statusType, eventMessages)); } - public static Attempt> Fail(TStatusType statusType, EventMessages eventMessages, TValue value) + public static Attempt?> Fail(TStatusType statusType, EventMessages eventMessages, TValue value) where TStatusType : struct { return Core.Attempt.Fail(new OperationResult(statusType, eventMessages, value)); @@ -237,7 +237,7 @@ namespace Umbraco.Cms.Core.Services return Core.Attempt.Fail(new OperationResult(statusType, eventMessages, value), exception); } - public static Attempt> Cannot(EventMessages eventMessages) + public static Attempt?> Cannot(EventMessages eventMessages) { return Core.Attempt.Fail(new OperationResult(OperationResultType.FailedCannot, eventMessages)); } diff --git a/src/Umbraco.Core/Services/Ordering.cs b/src/Umbraco.Core/Services/Ordering.cs index c90431f028..a3c4967abe 100644 --- a/src/Umbraco.Core/Services/Ordering.cs +++ b/src/Umbraco.Core/Services/Ordering.cs @@ -20,11 +20,11 @@ namespace Umbraco.Cms.Core.Services /// The can be null, meaning: not sorting. If it is the empty string, it becomes null. /// The can be the empty string, meaning: invariant. If it is null, it becomes the empty string. /// - public Ordering(string orderBy, Direction direction = Direction.Ascending, string? culture = null, bool isCustomField = false) + public Ordering(string? orderBy, Direction direction = Direction.Ascending, string? culture = null, bool isCustomField = false) { - OrderBy = orderBy.IfNullOrWhiteSpace(null); // empty is null and means, not sorting + OrderBy = orderBy?.IfNullOrWhiteSpace(null); // empty is null and means, not sorting Direction = direction; - Culture = culture.IfNullOrWhiteSpace(string.Empty); // empty is "" and means, invariant + Culture = culture?.IfNullOrWhiteSpace(string.Empty); // empty is "" and means, invariant IsCustomField = isCustomField; } @@ -51,7 +51,7 @@ namespace Umbraco.Cms.Core.Services /// /// Gets the name of the ordering field. /// - public string OrderBy { get; } + public string? OrderBy { get; } /// /// Gets the ordering direction. @@ -61,7 +61,7 @@ namespace Umbraco.Cms.Core.Services /// /// Gets (ISO) culture to consider when sorting multi-lingual fields. /// - public string Culture { get; } + public string? Culture { get; } /// /// Gets a value indicating whether the ordering field is a custom user property. diff --git a/src/Umbraco.Core/Services/PublishResult.cs b/src/Umbraco.Core/Services/PublishResult.cs index 2b01d45d68..ad5cae80ec 100644 --- a/src/Umbraco.Core/Services/PublishResult.cs +++ b/src/Umbraco.Core/Services/PublishResult.cs @@ -27,11 +27,11 @@ namespace Umbraco.Cms.Core.Services /// /// Gets the document. /// - public IContent Content => Entity; + public IContent? Content => Entity; /// /// Gets or sets the invalid properties, if the status failed due to validation. /// - public IEnumerable InvalidProperties { get; set; } + public IEnumerable? InvalidProperties { get; set; } } } diff --git a/src/Umbraco.Core/Services/SectionService.cs b/src/Umbraco.Core/Services/SectionService.cs index 93f6d624c3..b698579b65 100644 --- a/src/Umbraco.Core/Services/SectionService.cs +++ b/src/Umbraco.Core/Services/SectionService.cs @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core.Services } /// - public ISection GetByAlias(string appAlias) + public ISection? GetByAlias(string appAlias) => GetSections().FirstOrDefault(t => t.Alias.Equals(appAlias, StringComparison.OrdinalIgnoreCase)); } } diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index 2a77a562ae..20774bd7a2 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -7,38 +7,38 @@ namespace Umbraco.Cms.Core.Services /// public class ServiceContext { - private readonly Lazy _publicAccessService; - private readonly Lazy _domainService; - private readonly Lazy _auditService; - private readonly Lazy _localizedTextService; - private readonly Lazy _tagService; - private readonly Lazy _contentService; - private readonly Lazy _userService; - private readonly Lazy _memberService; - private readonly Lazy _mediaService; - private readonly Lazy _contentTypeService; - private readonly Lazy _mediaTypeService; - private readonly Lazy _dataTypeService; - private readonly Lazy _fileService; - private readonly Lazy _localizationService; - private readonly Lazy _packagingService; - private readonly Lazy _serverRegistrationService; - private readonly Lazy _entityService; - private readonly Lazy _relationService; - private readonly Lazy _macroService; - private readonly Lazy _memberTypeService; - private readonly Lazy _memberGroupService; - private readonly Lazy _notificationService; - private readonly Lazy _externalLoginService; - private readonly Lazy _redirectUrlService; - private readonly Lazy _consentService; - private readonly Lazy _keyValueService; - private readonly Lazy _contentTypeBaseServiceProvider; + private readonly Lazy? _publicAccessService; + private readonly Lazy? _domainService; + private readonly Lazy? _auditService; + private readonly Lazy? _localizedTextService; + private readonly Lazy? _tagService; + private readonly Lazy? _contentService; + private readonly Lazy? _userService; + private readonly Lazy? _memberService; + private readonly Lazy? _mediaService; + private readonly Lazy? _contentTypeService; + private readonly Lazy? _mediaTypeService; + private readonly Lazy? _dataTypeService; + private readonly Lazy? _fileService; + private readonly Lazy? _localizationService; + private readonly Lazy? _packagingService; + private readonly Lazy? _serverRegistrationService; + private readonly Lazy? _entityService; + private readonly Lazy? _relationService; + private readonly Lazy? _macroService; + private readonly Lazy? _memberTypeService; + private readonly Lazy? _memberGroupService; + private readonly Lazy? _notificationService; + private readonly Lazy? _externalLoginService; + private readonly Lazy? _redirectUrlService; + private readonly Lazy? _consentService; + private readonly Lazy? _keyValueService; + private readonly Lazy? _contentTypeBaseServiceProvider; /// /// Initializes a new instance of the class with lazy services. /// - public ServiceContext(Lazy publicAccessService, Lazy domainService, Lazy auditService, Lazy localizedTextService, Lazy tagService, Lazy contentService, Lazy userService, Lazy memberService, Lazy mediaService, Lazy contentTypeService, Lazy mediaTypeService, Lazy dataTypeService, Lazy fileService, Lazy localizationService, Lazy packagingService, Lazy serverRegistrationService, Lazy entityService, Lazy relationService, Lazy macroService, Lazy memberTypeService, Lazy memberGroupService, Lazy notificationService, Lazy externalLoginService, Lazy redirectUrlService, Lazy consentService, Lazy keyValueService, Lazy contentTypeBaseServiceProvider) + public ServiceContext(Lazy? publicAccessService, Lazy? domainService, Lazy? auditService, Lazy? localizedTextService, Lazy? tagService, Lazy? contentService, Lazy? userService, Lazy? memberService, Lazy? mediaService, Lazy? contentTypeService, Lazy? mediaTypeService, Lazy? dataTypeService, Lazy? fileService, Lazy? localizationService, Lazy? packagingService, Lazy? serverRegistrationService, Lazy? entityService, Lazy? relationService, Lazy? macroService, Lazy? memberTypeService, Lazy? memberGroupService, Lazy? notificationService, Lazy? externalLoginService, Lazy? redirectUrlService, Lazy? consentService, Lazy? keyValueService, Lazy? contentTypeBaseServiceProvider) { _publicAccessService = publicAccessService; _domainService = domainService; @@ -76,35 +76,35 @@ namespace Umbraco.Cms.Core.Services /// Using a true constructor for this confuses DI containers. /// public static ServiceContext CreatePartial( - IContentService contentService = null, - IMediaService mediaService = null, - IContentTypeService contentTypeService = null, - IMediaTypeService mediaTypeService = null, - IDataTypeService dataTypeService = null, - IFileService fileService = null, - ILocalizationService localizationService = null, - IPackagingService packagingService = null, - IEntityService entityService = null, - IRelationService relationService = null, - IMemberGroupService memberGroupService = null, - IMemberTypeService memberTypeService = null, - IMemberService memberService = null, - IUserService userService = null, - ITagService tagService = null, - INotificationService notificationService = null, - ILocalizedTextService localizedTextService = null, - IAuditService auditService = null, - IDomainService domainService = null, - IMacroService macroService = null, - IPublicAccessService publicAccessService = null, - IExternalLoginService externalLoginService = null, - IServerRegistrationService serverRegistrationService = null, - IRedirectUrlService redirectUrlService = null, - IConsentService consentService = null, - IKeyValueService keyValueService = null, - IContentTypeBaseServiceProvider contentTypeBaseServiceProvider = null) + IContentService? contentService = null, + IMediaService? mediaService = null, + IContentTypeService? contentTypeService = null, + IMediaTypeService? mediaTypeService = null, + IDataTypeService? dataTypeService = null, + IFileService? fileService = null, + ILocalizationService? localizationService = null, + IPackagingService? packagingService = null, + IEntityService? entityService = null, + IRelationService? relationService = null, + IMemberGroupService? memberGroupService = null, + IMemberTypeService? memberTypeService = null, + IMemberService? memberService = null, + IUserService? userService = null, + ITagService? tagService = null, + INotificationService? notificationService = null, + ILocalizedTextService? localizedTextService = null, + IAuditService? auditService = null, + IDomainService? domainService = null, + IMacroService? macroService = null, + IPublicAccessService? publicAccessService = null, + IExternalLoginService? externalLoginService = null, + IServerRegistrationService? serverRegistrationService = null, + IRedirectUrlService? redirectUrlService = null, + IConsentService? consentService = null, + IKeyValueService? keyValueService = null, + IContentTypeBaseServiceProvider? contentTypeBaseServiceProvider = null) { - Lazy Lazy(T service) => service == null ? null : new Lazy(() => service); + Lazy? Lazy(T? service) => service == null ? null : new Lazy(() => service); return new ServiceContext( Lazy(publicAccessService), @@ -140,136 +140,136 @@ namespace Umbraco.Cms.Core.Services /// /// Gets the /// - public IPublicAccessService PublicAccessService => _publicAccessService.Value; + public IPublicAccessService? PublicAccessService => _publicAccessService?.Value; /// /// Gets the /// - public IDomainService DomainService => _domainService.Value; + public IDomainService? DomainService => _domainService?.Value; /// /// Gets the /// - public IAuditService AuditService => _auditService.Value; + public IAuditService? AuditService => _auditService?.Value; /// /// Gets the /// - public ILocalizedTextService TextService => _localizedTextService.Value; + public ILocalizedTextService? TextService => _localizedTextService?.Value; /// /// Gets the /// - public INotificationService NotificationService => _notificationService.Value; + public INotificationService? NotificationService => _notificationService?.Value; /// /// Gets the /// - public IServerRegistrationService ServerRegistrationService => _serverRegistrationService.Value; + public IServerRegistrationService? ServerRegistrationService => _serverRegistrationService?.Value; /// /// Gets the /// - public ITagService TagService => _tagService.Value; + public ITagService? TagService => _tagService?.Value; /// /// Gets the /// - public IMacroService MacroService => _macroService.Value; + public IMacroService? MacroService => _macroService?.Value; /// /// Gets the /// - public IEntityService EntityService => _entityService.Value; + public IEntityService? EntityService => _entityService?.Value; /// /// Gets the /// - public IRelationService RelationService => _relationService.Value; + public IRelationService? RelationService => _relationService?.Value; /// /// Gets the /// - public IContentService ContentService => _contentService.Value; + public IContentService? ContentService => _contentService?.Value; /// /// Gets the /// - public IContentTypeService ContentTypeService => _contentTypeService.Value; + public IContentTypeService? ContentTypeService => _contentTypeService?.Value; /// /// Gets the /// - public IMediaTypeService MediaTypeService => _mediaTypeService.Value; + public IMediaTypeService? MediaTypeService => _mediaTypeService?.Value; /// /// Gets the /// - public IDataTypeService DataTypeService => _dataTypeService.Value; + public IDataTypeService? DataTypeService => _dataTypeService?.Value; /// /// Gets the /// - public IFileService FileService => _fileService.Value; + public IFileService? FileService => _fileService?.Value; /// /// Gets the /// - public ILocalizationService LocalizationService => _localizationService.Value; + public ILocalizationService? LocalizationService => _localizationService?.Value; /// /// Gets the /// - public IMediaService MediaService => _mediaService.Value; + public IMediaService? MediaService => _mediaService?.Value; /// /// Gets the /// - public IPackagingService PackagingService => _packagingService.Value; + public IPackagingService? PackagingService => _packagingService?.Value; /// /// Gets the /// - public IUserService UserService => _userService.Value; + public IUserService? UserService => _userService?.Value; /// /// Gets the /// - public IMemberService MemberService => _memberService.Value; + public IMemberService? MemberService => _memberService?.Value; /// /// Gets the MemberTypeService /// - public IMemberTypeService MemberTypeService => _memberTypeService.Value; + public IMemberTypeService? MemberTypeService => _memberTypeService?.Value; /// /// Gets the MemberGroupService /// - public IMemberGroupService MemberGroupService => _memberGroupService.Value; + public IMemberGroupService? MemberGroupService => _memberGroupService?.Value; /// /// Gets the ExternalLoginService. /// - public IExternalLoginService ExternalLoginService => _externalLoginService.Value; + public IExternalLoginService? ExternalLoginService => _externalLoginService?.Value; /// /// Gets the RedirectUrlService. /// - public IRedirectUrlService RedirectUrlService => _redirectUrlService.Value; + public IRedirectUrlService? RedirectUrlService => _redirectUrlService?.Value; /// /// Gets the ConsentService. /// - public IConsentService ConsentService => _consentService.Value; + public IConsentService? ConsentService => _consentService?.Value; /// /// Gets the KeyValueService. /// - public IKeyValueService KeyValueService => _keyValueService.Value; + public IKeyValueService? KeyValueService => _keyValueService?.Value; /// /// Gets the ContentTypeServiceBaseFactory. /// - public IContentTypeBaseServiceProvider ContentTypeBaseServices => _contentTypeBaseServiceProvider.Value; + public IContentTypeBaseServiceProvider? ContentTypeBaseServices => _contentTypeBaseServiceProvider?.Value; } } diff --git a/src/Umbraco.Core/Services/TreeService.cs b/src/Umbraco.Core/Services/TreeService.cs index 9dbe5edb4f..f325712d77 100644 --- a/src/Umbraco.Core/Services/TreeService.cs +++ b/src/Umbraco.Core/Services/TreeService.cs @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.Services } /// - public Tree GetByAlias(string treeAlias) => _treeCollection.FirstOrDefault(x => x.TreeAlias == treeAlias); + public Tree? GetByAlias(string treeAlias) => _treeCollection.FirstOrDefault(x => x.TreeAlias == treeAlias); /// public IEnumerable GetAll(TreeUse use = TreeUse.Main) diff --git a/src/Umbraco.Core/Services/UserServiceExtensions.cs b/src/Umbraco.Core/Services/UserServiceExtensions.cs index 57d09077fc..2f0d8eac12 100644 --- a/src/Umbraco.Core/Services/UserServiceExtensions.cs +++ b/src/Umbraco.Core/Services/UserServiceExtensions.cs @@ -10,7 +10,7 @@ namespace Umbraco.Extensions { public static class UserServiceExtensions { - public static EntityPermission GetPermissions(this IUserService userService, IUser user, string path) + public static EntityPermission? GetPermissions(this IUserService userService, IUser user, string path) { var ids = path.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries) .Select(x => int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value) ? Attempt.Succeed(value) : Attempt.Fail()) diff --git a/src/Umbraco.Core/Settable.cs b/src/Umbraco.Core/Settable.cs index 0d2802226f..07f53c2080 100644 --- a/src/Umbraco.Core/Settable.cs +++ b/src/Umbraco.Core/Settable.cs @@ -8,15 +8,18 @@ namespace Umbraco.Cms.Core /// The type of the value public class Settable { - private T _value; + private T? _value; /// /// Assigns a value to this instance. /// /// The value. - public void Set(T value) + public void Set(T? value) { - HasValue = true; + if (value is not null) + { + HasValue = true; + } _value = value; } @@ -50,7 +53,7 @@ namespace Umbraco.Cms.Core /// /// An exception is thrown if the HasValue property is false. /// No value has been assigned to this instance. - public T Value + public T? Value { get { @@ -66,7 +69,7 @@ namespace Umbraco.Cms.Core /// /// The value assigned to this instance, if a value has been assigned, /// else the default value of . - public T ValueOrDefault() + public T? ValueOrDefault() { return HasValue ? _value : default(T); } @@ -78,15 +81,15 @@ namespace Umbraco.Cms.Core /// The default value. /// The value assigned to this instance, if a value has been assigned, /// else . - public T ValueOrDefault(T defaultValue) + public T? ValueOrDefault(T defaultValue) { return HasValue ? _value : defaultValue; } /// - public override string ToString() + public override string? ToString() { - return HasValue ? _value.ToString() : "void"; + return HasValue ? _value?.ToString() : "void"; } } } diff --git a/src/Umbraco.Core/SimpleMainDom.cs b/src/Umbraco.Core/SimpleMainDom.cs index 204734d918..3f4bd1ce7c 100644 --- a/src/Umbraco.Core/SimpleMainDom.cs +++ b/src/Umbraco.Core/SimpleMainDom.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Core public bool Acquire(IApplicationShutdownRegistry hostingEnvironment) => true; /// - public bool Register(Action install, Action release, int weight = 100) + public bool Register(Action? install, Action? release, int weight = 100) { lock (_locko) { diff --git a/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs b/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs index b540f3683a..a95a3edfc2 100644 --- a/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs +++ b/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs @@ -41,15 +41,19 @@ namespace Umbraco.Cms.Core.Strings.Css return rules; } - public static string ReplaceRule(string input, string oldRuleName, StylesheetRule? rule) + public static string? ReplaceRule(string? input, string oldRuleName, StylesheetRule? rule) { var contents = input; - var ruleRegex = new Regex(string.Format(RuleRegexFormat, oldRuleName.EscapeRegexSpecialCharacters()), RegexOptions.IgnoreCase | RegexOptions.Singleline); - contents = ruleRegex.Replace(contents, rule != null ? rule.ToString() : ""); + if (contents is not null) + { + var ruleRegex = new Regex(string.Format(RuleRegexFormat, oldRuleName.EscapeRegexSpecialCharacters()), RegexOptions.IgnoreCase | RegexOptions.Singleline); + contents = ruleRegex.Replace(contents, rule != null ? rule.ToString() : ""); + } + return contents; } - public static string AppendRule(string input, StylesheetRule rule) + public static string AppendRule(string? input, StylesheetRule rule) { var contents = input; contents += Environment.NewLine + Environment.NewLine + rule; diff --git a/src/Umbraco.Core/Sync/RefreshInstruction.cs b/src/Umbraco.Core/Sync/RefreshInstruction.cs index c01d758583..b02cbc81e0 100644 --- a/src/Umbraco.Core/Sync/RefreshInstruction.cs +++ b/src/Umbraco.Core/Sync/RefreshInstruction.cs @@ -153,7 +153,7 @@ namespace Umbraco.Cms.Core.Sync /// /// Gets or sets the ids data value. /// - public string JsonIds { get; set; } + public string? JsonIds { get; set; } /// /// Gets or sets the number of Ids contained in the JsonIds json value. @@ -166,7 +166,7 @@ namespace Umbraco.Cms.Core.Sync /// /// Gets or sets the payload data value. /// - public string JsonPayload { get; set; } + public string? JsonPayload { get; set; } protected bool Equals(RefreshInstruction other) => RefreshType == other.RefreshType @@ -176,7 +176,7 @@ namespace Umbraco.Cms.Core.Sync && string.Equals(JsonIds, other.JsonIds) && string.Equals(JsonPayload, other.JsonPayload); - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is null) { diff --git a/src/Umbraco.Core/SystemLock.cs b/src/Umbraco.Core/SystemLock.cs index a8647f6cc8..d39d6ecbce 100644 --- a/src/Umbraco.Core/SystemLock.cs +++ b/src/Umbraco.Core/SystemLock.cs @@ -22,16 +22,16 @@ namespace Umbraco.Cms.Core // public class SystemLock { - private readonly SemaphoreSlim _semaphore; - private readonly Semaphore _semaphore2; - private readonly IDisposable _releaser; - private readonly Task _releaserTask; + private readonly SemaphoreSlim? _semaphore; + private readonly Semaphore? _semaphore2; + private readonly IDisposable? _releaser; + private readonly Task? _releaserTask; public SystemLock() : this(null) { } - public SystemLock(string name) + public SystemLock(string? name) { // WaitOne() waits until count > 0 then decrements count // Release() increments count @@ -58,7 +58,7 @@ namespace Umbraco.Cms.Core } } - private IDisposable CreateReleaser() + private IDisposable? CreateReleaser() { // for anonymous semaphore, use the unique releaser, else create a new one return _semaphore != null @@ -66,20 +66,20 @@ namespace Umbraco.Cms.Core : new NamedSemaphoreReleaser(_semaphore2); } - public IDisposable Lock() + public IDisposable? Lock() { if (_semaphore != null) _semaphore.Wait(); else - _semaphore2.WaitOne(); + _semaphore2?.WaitOne(); return _releaser ?? CreateReleaser(); // anonymous vs named } - public IDisposable Lock(int millisecondsTimeout) + public IDisposable? Lock(int millisecondsTimeout) { var entered = _semaphore != null ? _semaphore.Wait(millisecondsTimeout) - : _semaphore2.WaitOne(millisecondsTimeout); + : _semaphore2?.WaitOne(millisecondsTimeout); if (entered == false) throw new TimeoutException("Failed to enter the lock within timeout."); return _releaser ?? CreateReleaser(); // anonymous vs named @@ -90,9 +90,9 @@ namespace Umbraco.Cms.Core private class NamedSemaphoreReleaser : CriticalFinalizerObject, IDisposable { - private readonly Semaphore _semaphore; + private readonly Semaphore? _semaphore; - internal NamedSemaphoreReleaser(Semaphore semaphore) + internal NamedSemaphoreReleaser(Semaphore? semaphore) { _semaphore = semaphore; } @@ -115,13 +115,13 @@ namespace Umbraco.Cms.Core { try { - _semaphore.Release(); + _semaphore?.Release(); } finally { try { - _semaphore.Dispose(); + _semaphore?.Dispose(); } catch { } } diff --git a/src/Umbraco.Core/Telemetry/ITelemetryService.cs b/src/Umbraco.Core/Telemetry/ITelemetryService.cs index 60070481f3..bb832bfd7e 100644 --- a/src/Umbraco.Core/Telemetry/ITelemetryService.cs +++ b/src/Umbraco.Core/Telemetry/ITelemetryService.cs @@ -10,6 +10,6 @@ namespace Umbraco.Cms.Core.Telemetry /// /// Try and get the /// - bool TryGetTelemetryReportData(out TelemetryReportData telemetryReportData); + bool TryGetTelemetryReportData(out TelemetryReportData? telemetryReportData); } } diff --git a/src/Umbraco.Core/Telemetry/Models/PackageTelemetry.cs b/src/Umbraco.Core/Telemetry/Models/PackageTelemetry.cs index 8b7aa4bc0c..c23a30648b 100644 --- a/src/Umbraco.Core/Telemetry/Models/PackageTelemetry.cs +++ b/src/Umbraco.Core/Telemetry/Models/PackageTelemetry.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.Telemetry.Models /// Gets or sets the name of the installed package. /// [DataMember(Name = "name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the version of the installed package. diff --git a/src/Umbraco.Core/Telemetry/TelemetryService.cs b/src/Umbraco.Core/Telemetry/TelemetryService.cs index efc8e4401a..7927772e0c 100644 --- a/src/Umbraco.Core/Telemetry/TelemetryService.cs +++ b/src/Umbraco.Core/Telemetry/TelemetryService.cs @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.Telemetry } /// - public bool TryGetTelemetryReportData(out TelemetryReportData telemetryReportData) + public bool TryGetTelemetryReportData(out TelemetryReportData? telemetryReportData) { if (TryGetTelemetryId(out Guid telemetryId) is false) { diff --git a/src/Umbraco.Core/Templates/HtmlImageSourceParser.cs b/src/Umbraco.Core/Templates/HtmlImageSourceParser.cs index c14a7a7bdf..46ac9fb6e7 100644 --- a/src/Umbraco.Core/Templates/HtmlImageSourceParser.cs +++ b/src/Umbraco.Core/Templates/HtmlImageSourceParser.cs @@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.Templates this._getMediaUrl = getMediaUrl; } - private readonly IPublishedUrlProvider _publishedUrlProvider; + private readonly IPublishedUrlProvider? _publishedUrlProvider; public HtmlImageSourceParser(IPublishedUrlProvider publishedUrlProvider) { @@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.Templates private static readonly Regex DataUdiAttributeRegex = new Regex(@"data-udi=\\?(?:""|')(?umb://[A-z0-9\-]+/[A-z0-9]+)\\?(?:""|')", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); - private Func _getMediaUrl; + private Func? _getMediaUrl; /// /// Parses out media UDIs from an html string based on 'data-udi' html attributes @@ -56,7 +56,7 @@ namespace Umbraco.Cms.Core.Templates public string EnsureImageSources(string text) { if(_getMediaUrl == null) - _getMediaUrl = (guid) => _publishedUrlProvider.GetMediaUrl(guid); + _getMediaUrl = (guid) => _publishedUrlProvider?.GetMediaUrl(guid); return ResolveImgPattern.Replace(text, match => { diff --git a/src/Umbraco.Core/Templates/HtmlLocalLinkParser.cs b/src/Umbraco.Core/Templates/HtmlLocalLinkParser.cs index a75fd3dee9..27c9c25062 100644 --- a/src/Umbraco.Core/Templates/HtmlLocalLinkParser.cs +++ b/src/Umbraco.Core/Templates/HtmlLocalLinkParser.cs @@ -26,11 +26,11 @@ namespace Umbraco.Cms.Core.Templates _publishedUrlProvider = publishedUrlProvider; } - public IEnumerable FindUdisFromLocalLinks(string text) + public IEnumerable FindUdisFromLocalLinks(string text) { - foreach ((int? intId, GuidUdi udi, string tagValue) in FindLocalLinkIds(text)) + foreach ((int? intId, GuidUdi? udi, string tagValue) in FindLocalLinkIds(text)) { - if (udi != null) + if (udi is null) yield return udi; // In v8, we only care abuot UDIs } } @@ -53,7 +53,7 @@ namespace Umbraco.Cms.Core.Templates return EnsureInternalLinks(text); } - using (umbracoContext.ForcedPreview(preview)) // force for URL provider + using (umbracoContext!.ForcedPreview(preview)) // force for URL provider { return EnsureInternalLinks(text); } @@ -72,14 +72,14 @@ namespace Umbraco.Cms.Core.Templates throw new InvalidOperationException("Could not parse internal links, there is no current UmbracoContext"); } - foreach((int? intId, GuidUdi udi, string tagValue) in FindLocalLinkIds(text)) + foreach((int? intId, GuidUdi? udi, string tagValue) in FindLocalLinkIds(text)) { - if (udi != null) + if (udi is null) { var newLink = "#"; - if (udi.EntityType == Constants.UdiEntityType.Document) + if (udi?.EntityType == Constants.UdiEntityType.Document) newLink = _publishedUrlProvider.GetUrl(udi.Guid); - else if (udi.EntityType == Constants.UdiEntityType.Media) + else if (udi?.EntityType == Constants.UdiEntityType.Media) newLink = _publishedUrlProvider.GetMediaUrl(udi.Guid); if (newLink == null) @@ -97,7 +97,7 @@ namespace Umbraco.Cms.Core.Templates return text; } - private IEnumerable<(int? intId, GuidUdi udi, string tagValue)> FindLocalLinkIds(string text) + private IEnumerable<(int? intId, GuidUdi? udi, string tagValue)> FindLocalLinkIds(string text) { // Parse internal links var tags = LocalLinkPattern.Matches(text); @@ -111,7 +111,7 @@ namespace Umbraco.Cms.Core.Templates if (UdiParser.TryParse(id, out var udi)) { var guidUdi = udi as GuidUdi; - if (guidUdi != null) + if (guidUdi is null) yield return (null, guidUdi, tag.Value); } diff --git a/src/Umbraco.Core/Templates/HtmlUrlParser.cs b/src/Umbraco.Core/Templates/HtmlUrlParser.cs index e28aca9ed5..39c82f00ab 100644 --- a/src/Umbraco.Core/Templates/HtmlUrlParser.cs +++ b/src/Umbraco.Core/Templates/HtmlUrlParser.cs @@ -45,7 +45,7 @@ namespace Umbraco.Cms.Core.Templates { // find all relative URLs (ie. URLs that contain ~) var tags = ResolveUrlPattern.Matches(text); - _logger.LogDebug("After regex: {Duration} matched: {TagsCount}", timer.Stopwatch.ElapsedMilliseconds, tags.Count); + _logger.LogDebug("After regex: {Duration} matched: {TagsCount}", timer?.Stopwatch.ElapsedMilliseconds, tags.Count); foreach (Match tag in tags) { var url = ""; diff --git a/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs b/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs index a8e0725107..98e8baf4e8 100644 --- a/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs +++ b/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs @@ -57,7 +57,7 @@ namespace Umbraco.Cms.Core.Templates public async Task RenderMacroAsync(int contentId, string alias) => await RenderMacroAsync(contentId, alias, new { }); /// - public async Task RenderMacroAsync(int contentId, string alias, object parameters) => await RenderMacroAsync(contentId, alias, parameters?.ToDictionary()); + public async Task RenderMacroAsync(int contentId, string alias, object parameters) => await RenderMacroAsync(contentId, alias, parameters.ToDictionary()); /// public async Task RenderMacroAsync(int contentId, string alias, IDictionary parameters) diff --git a/src/Umbraco.Core/Tour/BackOfficeTourFilter.cs b/src/Umbraco.Core/Tour/BackOfficeTourFilter.cs index 281f2a1663..3fba765f83 100644 --- a/src/Umbraco.Core/Tour/BackOfficeTourFilter.cs +++ b/src/Umbraco.Core/Tour/BackOfficeTourFilter.cs @@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core.Tour /// Example, pluginName = "hello", tourFileName="stuff", tourAlias=NULL = we will filter out the tour file "stuff" from the plugin "hello" but not from other plugins if the same file name exists. /// Example, tourAlias="test.*" = we will filter out all tour aliases that start with the word "test" regardless of the plugin or file name /// - public BackOfficeTourFilter(Regex pluginName, Regex tourFileName, Regex tourAlias) + public BackOfficeTourFilter(Regex? pluginName, Regex? tourFileName, Regex? tourAlias) { PluginName = pluginName; TourFileName = tourFileName; @@ -30,17 +30,17 @@ namespace Umbraco.Cms.Core.Tour /// /// Gets the plugin name filtering regex. /// - public Regex PluginName { get; } + public Regex? PluginName { get; } /// /// Gets the tour filename filtering regex. /// - public Regex TourFileName { get; } + public Regex? TourFileName { get; } /// /// Gets the tour alias filtering regex. /// - public Regex TourAlias { get; } + public Regex? TourAlias { get; } /// /// Creates a filter to filter on the plugin name. diff --git a/src/Umbraco.Core/Trees/ISearchableTree.cs b/src/Umbraco.Core/Trees/ISearchableTree.cs index 9464dbefd3..743fd10a87 100644 --- a/src/Umbraco.Core/Trees/ISearchableTree.cs +++ b/src/Umbraco.Core/Trees/ISearchableTree.cs @@ -22,6 +22,6 @@ namespace Umbraco.Cms.Core.Trees /// A starting point for the search, generally a node id, but for members this is a member type alias /// /// - IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null); + IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null); } } diff --git a/src/Umbraco.Core/Trees/MenuItemCollection.cs b/src/Umbraco.Core/Trees/MenuItemCollection.cs index 0a83255368..66bdba55d4 100644 --- a/src/Umbraco.Core/Trees/MenuItemCollection.cs +++ b/src/Umbraco.Core/Trees/MenuItemCollection.cs @@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.Trees /// Sets the default menu item alias to be shown when the menu is launched - this is optional and if not set then the menu will just be shown normally. /// [DataMember(Name = "defaultAlias")] - public string DefaultMenuAlias { get; set; } + public string? DefaultMenuAlias { get; set; } /// /// The list of menu items diff --git a/src/Umbraco.Core/Trees/MenuItemList.cs b/src/Umbraco.Core/Trees/MenuItemList.cs index 7588fe778a..b3fe420602 100644 --- a/src/Umbraco.Core/Trees/MenuItemList.cs +++ b/src/Umbraco.Core/Trees/MenuItemList.cs @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.Trees /// /// The used to localize the action name based on its alias /// Whether or not this action opens a dialog - public MenuItem Add(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) + public MenuItem? Add(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) where T : IAction { var item = CreateMenuItem(textService, hasSeparator, opensDialog); @@ -50,7 +50,7 @@ namespace Umbraco.Cms.Core.Trees return null; } - private MenuItem CreateMenuItem(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) + private MenuItem? CreateMenuItem(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) where T : IAction { var item = _actionCollection.GetAction(); diff --git a/src/Umbraco.Core/Trees/Tree.cs b/src/Umbraco.Core/Trees/Tree.cs index a3b3d42b14..7ba01880d7 100644 --- a/src/Umbraco.Core/Trees/Tree.cs +++ b/src/Umbraco.Core/Trees/Tree.cs @@ -49,7 +49,7 @@ namespace Umbraco.Cms.Core.Trees /// public Type TreeControllerType { get; } - public static string GetRootNodeDisplayName(ITree tree, ILocalizedTextService textService) + public static string? GetRootNodeDisplayName(ITree tree, ILocalizedTextService textService) { var label = $"[{tree.TreeAlias}]"; diff --git a/src/Umbraco.Core/Trees/TreeNode.cs b/src/Umbraco.Core/Trees/TreeNode.cs index 4e509da259..8ecab61fb3 100644 --- a/src/Umbraco.Core/Trees/TreeNode.cs +++ b/src/Umbraco.Core/Trees/TreeNode.cs @@ -50,7 +50,7 @@ namespace Umbraco.Cms.Core.Trees /// The tree nodetype which refers to the type of node rendered in the tree /// [DataMember(Name = "nodeType")] - public string NodeType { get; set; } + public string? NodeType { get; set; } /// /// Optional: The Route path for the editor for this node @@ -59,7 +59,7 @@ namespace Umbraco.Cms.Core.Trees /// If this is not set, then the route path will be automatically determined by: {section}/edit/{id} /// [DataMember(Name = "routePath")] - public string RoutePath { get; set; } + public string? RoutePath { get; set; } /// /// The JSON URL to load the nodes children @@ -86,7 +86,7 @@ namespace Umbraco.Cms.Core.Trees return true; } - if (Icon.StartsWith("..")) + if (Icon!.StartsWith("..")) return false; diff --git a/src/Umbraco.Core/Udi.cs b/src/Umbraco.Core/Udi.cs index 208ac536c1..02979646a0 100644 --- a/src/Umbraco.Core/Udi.cs +++ b/src/Umbraco.Core/Udi.cs @@ -42,9 +42,9 @@ namespace Umbraco.Cms.Core /// public string EntityType { get; private set; } - public int CompareTo(Udi other) + public int CompareTo(Udi? other) { - return string.Compare(UriValue.ToString(), other.UriValue.ToString(), StringComparison.OrdinalIgnoreCase); + return string.Compare(UriValue.ToString(), other?.UriValue.ToString(), StringComparison.OrdinalIgnoreCase); } public override string ToString() @@ -143,10 +143,10 @@ namespace Umbraco.Cms.Core return this; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { var other = obj as Udi; - return other != null && GetType() == other.GetType() && UriValue == other.UriValue; + return other is not null && GetType() == other.GetType() && UriValue == other.UriValue; } public override int GetHashCode() diff --git a/src/Umbraco.Core/UdiRange.cs b/src/Umbraco.Core/UdiRange.cs index 8282ab4e3f..ca5b07bf36 100644 --- a/src/Umbraco.Core/UdiRange.cs +++ b/src/Umbraco.Core/UdiRange.cs @@ -60,7 +60,7 @@ namespace Umbraco.Cms.Core public static UdiRange Parse(string s) { - Uri uri; + Uri? uri; if (Uri.IsWellFormedUriString(s, UriKind.Absolute) == false || Uri.TryCreate(s, UriKind.Absolute, out uri) == false) diff --git a/src/Umbraco.Core/UdiTypeConverter.cs b/src/Umbraco.Core/UdiTypeConverter.cs index 3b4015e8f0..c443b1817b 100644 --- a/src/Umbraco.Core/UdiTypeConverter.cs +++ b/src/Umbraco.Core/UdiTypeConverter.cs @@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core /// internal class UdiTypeConverter : TypeConverter { - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { if (sourceType == typeof(string)) { @@ -21,11 +21,11 @@ namespace Umbraco.Cms.Core return base.CanConvertFrom(context, sourceType); } - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is string) { - Udi udi; + Udi? udi; if (UdiParser.TryParse((string)value, out udi)) { return udi; diff --git a/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs b/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs index 5b7388d4f7..033206a453 100644 --- a/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs +++ b/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs @@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core.Web /// /// Tries to get the object. /// - public bool TryGetUmbracoContext(out IUmbracoContext umbracoContext) + public bool TryGetUmbracoContext(out IUmbracoContext? umbracoContext) { umbracoContext = Value; diff --git a/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs b/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs index c0cd6061be..fd37126b7d 100644 --- a/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs +++ b/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs @@ -7,7 +7,7 @@ namespace Umbraco.Cms.Core.Web /// public interface IUmbracoContextAccessor { - bool TryGetUmbracoContext(out IUmbracoContext umbracoContext); + bool TryGetUmbracoContext(out IUmbracoContext? umbracoContext); void Clear(); void Set(IUmbracoContext umbracoContext); } diff --git a/src/Umbraco.Core/WebAssets/AssetFile.cs b/src/Umbraco.Core/WebAssets/AssetFile.cs index 78249edae9..c10a423a99 100644 --- a/src/Umbraco.Core/WebAssets/AssetFile.cs +++ b/src/Umbraco.Core/WebAssets/AssetFile.cs @@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core.WebAssets { #region IAssetFile Members - public string FilePath { get; set; } + public string? FilePath { get; set; } public AssetType DependencyType { get; } #endregion diff --git a/src/Umbraco.Core/WebAssets/BundlingOptions.cs b/src/Umbraco.Core/WebAssets/BundlingOptions.cs index 6a3c0b9bd1..64b9e72e17 100644 --- a/src/Umbraco.Core/WebAssets/BundlingOptions.cs +++ b/src/Umbraco.Core/WebAssets/BundlingOptions.cs @@ -26,7 +26,7 @@ namespace Umbraco.Cms.Core.WebAssets /// public bool EnabledCompositeFiles { get; } - public override bool Equals(object obj) => obj is BundlingOptions options && Equals(options); + public override bool Equals(object? obj) => obj is BundlingOptions options && Equals(options); public bool Equals(BundlingOptions other) => OptimizeOutput == other.OptimizeOutput && EnabledCompositeFiles == other.EnabledCompositeFiles; public override int GetHashCode() diff --git a/src/Umbraco.Core/WebAssets/IAssetFile.cs b/src/Umbraco.Core/WebAssets/IAssetFile.cs index 6992af7f30..dd66afe4a7 100644 --- a/src/Umbraco.Core/WebAssets/IAssetFile.cs +++ b/src/Umbraco.Core/WebAssets/IAssetFile.cs @@ -2,7 +2,7 @@ { public interface IAssetFile { - string FilePath { get; set; } + string? FilePath { get; set; } AssetType DependencyType { get; } } } diff --git a/src/Umbraco.Core/Xml/DynamicContext.cs b/src/Umbraco.Core/Xml/DynamicContext.cs index 338984867e..7547b7cc31 100644 --- a/src/Umbraco.Core/Xml/DynamicContext.cs +++ b/src/Umbraco.Core/Xml/DynamicContext.cs @@ -95,18 +95,18 @@ namespace Umbraco.Cms.Core.Xml /// /// Same as . /// - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { - var key = NameTable.Get(prefix); + var key = NameTable?.Get(prefix); return key == null ? null : base.LookupNamespace(key); } /// /// Same as . /// - public override string LookupPrefix(string uri) + public override string? LookupPrefix(string uri) { - var key = NameTable.Get(uri); + var key = NameTable?.Get(uri); return key == null ? null : base.LookupPrefix(key); } @@ -135,9 +135,9 @@ namespace Umbraco.Cms.Core.Xml /// /// The expression to compile /// A compiled . - public static XPathExpression Compile(string xpath) + public static XPathExpression? Compile(string xpath) { - return new XmlDocument().CreateNavigator().Compile(xpath); + return new XmlDocument().CreateNavigator()?.Compile(xpath); } #endregion Public Members @@ -194,10 +194,7 @@ namespace Umbraco.Cms.Core.Xml /// /// See . Not used in our implementation. /// - public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] argTypes) - { - return null; - } + public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] argTypes) => throw new NotImplementedException(); /// /// Resolves the dynamic variables added to the context. See . @@ -205,8 +202,8 @@ namespace Umbraco.Cms.Core.Xml public override IXsltContextVariable ResolveVariable(string prefix, string name) { IXsltContextVariable var; - _variables.TryGetValue(name, out var); - return var; + _variables.TryGetValue(name, out var!); + return var!; } #endregion Variable Handling Code diff --git a/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs b/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs index 5ebc575243..a77f14bce8 100644 --- a/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs +++ b/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs @@ -123,7 +123,7 @@ namespace Umbraco.Cms.Core.Xml.XPath /// The clone state. /// The clone maximum depth. /// Privately used for cloning a navigator. - private NavigableNavigator(NavigableNavigator orig, State state = null, int maxDepth = -1) + private NavigableNavigator(NavigableNavigator orig, State? state = null, int maxDepth = -1) : this(orig._source, rootId: 0, maxDepth: orig._maxDepth) { _nameTable = orig._nameTable; @@ -277,7 +277,7 @@ namespace Umbraco.Cms.Core.Xml.XPath /// /// Gets the underlying content object. /// - public override object UnderlyingObject => _state.Content; + public override object? UnderlyingObject => _state.Content; /// /// Creates a new XPathNavigator positioned at the same node as this XPathNavigator. @@ -310,11 +310,11 @@ namespace Umbraco.Cms.Core.Xml.XPath /// /// A new XPathNavigator using the same source and positioned at a new root. /// The new root can be above this navigator's root. - public XPathNavigator CloneWithNewRoot(int id, int maxDepth = int.MaxValue) + public XPathNavigator? CloneWithNewRoot(int id, int maxDepth = int.MaxValue) { DebugEnter("CloneWithNewRoot"); - State state = null; + State? state = null; if (id <= 0) { @@ -329,7 +329,7 @@ namespace Umbraco.Cms.Core.Xml.XPath } } - NavigableNavigator clone = null; + NavigableNavigator? clone = null; if (state != null) { @@ -369,10 +369,10 @@ namespace Umbraco.Cms.Core.Xml.XPath // - an XPathNavigator over a non-empty XML fragment // - a non-Xml-whitespace string // - null - isEmpty = _state.Content.Value(_state.FieldIndex) == null; + isEmpty = _state.Content?.Value(_state.FieldIndex) == null; break; case StatePosition.PropertyXml: - isEmpty = _state.XmlFragmentNavigator.IsEmptyElement; + isEmpty = _state.XmlFragmentNavigator?.IsEmptyElement ?? true; break; case StatePosition.Attribute: case StatePosition.PropertyText: @@ -400,7 +400,7 @@ namespace Umbraco.Cms.Core.Xml.XPath switch (_state.Position) { case StatePosition.PropertyXml: - isSame = _state.XmlFragmentNavigator.IsSamePosition(nav); + isSame = _state.XmlFragmentNavigator?.IsSamePosition(nav) ?? false; break; case StatePosition.Attribute: case StatePosition.Element: @@ -426,7 +426,7 @@ namespace Umbraco.Cms.Core.Xml.XPath get { DebugEnter("Name"); - string name; + string? name; switch (_state.Position) { @@ -435,10 +435,10 @@ namespace Umbraco.Cms.Core.Xml.XPath break; case StatePosition.Attribute: case StatePosition.PropertyElement: - name = _state.FieldIndex == -1 ? "id" : _state.CurrentFieldType.Name; + name = _state.FieldIndex == -1 ? "id" : _state.CurrentFieldType?.Name; break; case StatePosition.Element: - name = _state.Content.Type.Name; + name = _state.Content?.Type.Name; break; case StatePosition.PropertyText: name = string.Empty; @@ -506,7 +506,7 @@ namespace Umbraco.Cms.Core.Xml.XPath switch (_state.Position) { case StatePosition.PropertyXml: - succ = _state.XmlFragmentNavigator.MoveToFirstAttribute(); + succ = _state.XmlFragmentNavigator?.MoveToFirstAttribute() ?? false; break; case StatePosition.Element: _state.FieldIndex = -1; @@ -541,7 +541,7 @@ namespace Umbraco.Cms.Core.Xml.XPath switch (_state.Position) { case StatePosition.PropertyXml: - succ = _state.XmlFragmentNavigator.MoveToFirstChild(); + succ = _state.XmlFragmentNavigator?.MoveToFirstChild() ?? false; break; case StatePosition.Attribute: case StatePosition.PropertyText: @@ -599,7 +599,7 @@ namespace Umbraco.Cms.Core.Xml.XPath private bool MoveToFirstChildProperty() { - var valueForXPath = _state.Content.Value(_state.FieldIndex); + var valueForXPath = _state.Content?.Value(_state.FieldIndex); // value should be // - an XPathNavigator over a non-empty XML fragment @@ -676,7 +676,7 @@ namespace Umbraco.Cms.Core.Xml.XPath var state = _state; while (state.Parent != null) // root state has no parent state = state.Parent; - var navRootId = state.Content.Id; + var navRootId = state.Content?.Id; int contentId; if (int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out contentId)) @@ -704,7 +704,7 @@ namespace Umbraco.Cms.Core.Xml.XPath _state = new State(state.Content, null, null, 0, StatePosition.Element); while (content != null) { - _state = new State(content, _state, _state.Content.ChildIds, _state.Content.ChildIds.IndexOf(content.Id), StatePosition.Element); + _state = new State(content, _state, _state.Content?.ChildIds, _state.Content?.ChildIds.IndexOf(content.Id) ?? -1, StatePosition.Element); content = s.Count == 0 ? null : s.Pop(); } DebugState(); @@ -732,7 +732,7 @@ namespace Umbraco.Cms.Core.Xml.XPath switch (_state.Position) { case StatePosition.PropertyXml: - succ = _state.XmlFragmentNavigator.MoveToNext(); + succ = _state.XmlFragmentNavigator?.MoveToNext() ?? false; break; case StatePosition.Element: succ = false; @@ -791,7 +791,7 @@ namespace Umbraco.Cms.Core.Xml.XPath switch (_state.Position) { case StatePosition.PropertyXml: - succ = _state.XmlFragmentNavigator.MoveToPrevious(); + succ = _state.XmlFragmentNavigator?.MoveToPrevious() ?? false; break; case StatePosition.Element: succ = false; @@ -1029,7 +1029,7 @@ namespace Umbraco.Cms.Core.Xml.XPath get { DebugEnter("Value"); - string value; + string? value; switch (_state.Position) { @@ -1041,11 +1041,11 @@ namespace Umbraco.Cms.Core.Xml.XPath case StatePosition.PropertyElement: if (_state.FieldIndex == -1) { - value = _state.Content.Id.ToString(CultureInfo.InvariantCulture); + value = _state.Content?.Id.ToString(CultureInfo.InvariantCulture); } else { - var valueForXPath = _state.Content.Value(_state.FieldIndex); + var valueForXPath = _state.Content?.Value(_state.FieldIndex); // value should be // - an XPathNavigator over a non-empty XML fragment @@ -1118,7 +1118,7 @@ namespace Umbraco.Cms.Core.Xml.XPath // initialize a new state // used for creating the very first state // and also when moving to a child element - public State(INavigableContent content, State parent, IList siblings, int siblingIndex, StatePosition position) + public State(INavigableContent? content, State? parent, IList? siblings, int siblingIndex, StatePosition position) : this(position) { Content = content; @@ -1166,16 +1166,16 @@ namespace Umbraco.Cms.Core.Xml.XPath } // the parent state - public State Parent { get; private set; } + public State? Parent { get; private set; } // the depth public int Depth { get; } // the current content - private INavigableContent _content; + private INavigableContent? _content; // the current content - public INavigableContent Content + public INavigableContent? Content { get { @@ -1193,14 +1193,14 @@ namespace Umbraco.Cms.Core.Xml.XPath // the current content child ids public IList GetContentChildIds(int maxDepth) { - return Depth < maxDepth && _content.ChildIds != null ? _content.ChildIds : NoChildIds; + return Depth < maxDepth && _content?.ChildIds != null ? _content.ChildIds : NoChildIds; } // the index of the current content within Siblings public int SiblingIndex { get; set; } // the list of content identifiers for all children of the current content's parent - public IList Siblings { get; } + public IList? Siblings { get; } // the number of fields of the current content // properties include attributes and properties @@ -1212,14 +1212,18 @@ namespace Umbraco.Cms.Core.Xml.XPath // the current field type // beware, no check on the index - public INavigableFieldType CurrentFieldType => Content.Type.FieldTypes[FieldIndex]; + public INavigableFieldType? CurrentFieldType => Content?.Type.FieldTypes[FieldIndex]; // gets or sets the xml fragment navigator - public XPathNavigator XmlFragmentNavigator { get; set; } + public XPathNavigator? XmlFragmentNavigator { get; set; } // gets a value indicating whether this state is at the same position as another one. public bool IsSamePosition(State other) { + if (other.XmlFragmentNavigator is null || XmlFragmentNavigator is null) + { + return false; + } return other.Position == Position && (Position != StatePosition.PropertyXml || other.XmlFragmentNavigator.IsSamePosition(XmlFragmentNavigator)) && other.Content == Content diff --git a/src/Umbraco.Core/Xml/XmlHelper.cs b/src/Umbraco.Core/Xml/XmlHelper.cs index 6cbb888965..4f6d5ca2f4 100644 --- a/src/Umbraco.Core/Xml/XmlHelper.cs +++ b/src/Umbraco.Core/Xml/XmlHelper.cs @@ -40,7 +40,7 @@ namespace Umbraco.Cms.Core.Xml } else { - n.Attributes[name].Value = value; + n.Attributes[name]!.Value = value; } } @@ -73,7 +73,7 @@ namespace Umbraco.Cms.Core.Xml /// The xml string. /// The XPath document. /// A value indicating whether it has been possible to create the document. - public static bool TryCreateXPathDocument(string xml, out XPathDocument doc) + public static bool TryCreateXPathDocument(string xml, out XPathDocument? doc) { try { @@ -94,7 +94,7 @@ namespace Umbraco.Cms.Core.Xml /// The XPath document. /// A value indicating whether it has been possible to create the document. /// The value can be anything... Performance-wise, this is bad. - public static bool TryCreateXPathDocumentFromPropertyValue(object value, out XPathDocument doc) + public static bool TryCreateXPathDocumentFromPropertyValue(object value, out XPathDocument? doc) { // DynamicNode.ConvertPropertyValueByDataType first cleans the value by calling // XmlHelper.StripDashesInElementOrAttributeName - this is because the XML is @@ -109,7 +109,7 @@ namespace Umbraco.Cms.Core.Xml if (IsXmlWhitespace(xml)) return false; // string is whitespace, xml-wise if (TryCreateXPathDocument(xml, out doc) == false) return false; // string can't be parsed into xml - var nav = doc.CreateNavigator(); + var nav = doc!.CreateNavigator(); if (nav.MoveToFirstChild()) { //SD: This used to do this but the razor macros and the entire razor macros section is gone, it was all legacy, it seems this method isn't even @@ -137,14 +137,17 @@ namespace Umbraco.Cms.Core.Xml string childNodesXPath, Func orderBy) { - var sortedChildNodes = parentNode.SelectNodes(childNodesXPath).Cast() + var sortedChildNodes = parentNode.SelectNodes(childNodesXPath)?.Cast() .OrderBy(orderBy) .ToArray(); // append child nodes to last position, in sort-order // so all child nodes will go after the property nodes - foreach (var node in sortedChildNodes) - parentNode.AppendChild(node); // moves the node to the last position + if (sortedChildNodes is not null) + { + foreach (var node in sortedChildNodes) + parentNode.AppendChild(node); // moves the node to the last position + } } @@ -165,11 +168,11 @@ namespace Umbraco.Cms.Core.Xml Func orderBy) { var nodeSortOrder = orderBy(node); - var childNodesAndOrder = parentNode.SelectNodes(childNodesXPath).Cast() + var childNodesAndOrder = parentNode.SelectNodes(childNodesXPath)?.Cast() .Select(x => Tuple.Create(x, orderBy(x))).ToArray(); // only one node = node is in the right place already, obviously - if (childNodesAndOrder.Length == 1) return false; + if (childNodesAndOrder is null || childNodesAndOrder.Length == 1) return false; // find the first node with a sortOrder > node.sortOrder var i = 0; diff --git a/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs b/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs index d63335ba33..b5173e800e 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/DataTypeService.cs @@ -270,11 +270,15 @@ namespace Umbraco.Cms.Core.Services.Implement /// /// Id of the /// - public IDataType GetDataType(int id) + public IDataType GetDataType(int? id) { + if (id is null) + { + return null; + } using (var scope = ScopeProvider.CreateScope(autoComplete: true)) { - var dataType = _dataTypeRepository.Get(id); + var dataType = _dataTypeRepository.Get(id.Value); ConvertMissingEditorOfDataTypeToLabel(dataType); return dataType; }