diff --git a/src/Umbraco.Core/GuidUtils.cs b/src/Umbraco.Core/GuidUtils.cs
index 6a8938dcf0..347ddd573e 100644
--- a/src/Umbraco.Core/GuidUtils.cs
+++ b/src/Umbraco.Core/GuidUtils.cs
@@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core
/// The seconds guid.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Guid Combine(Guid a, Guid b)
+ public static Guid? Combine(Guid? a, Guid? b)
{
var ad = new DecomposedGuid(a);
var bd = new DecomposedGuid(b);
@@ -34,11 +34,11 @@ namespace Umbraco.Cms.Core
[StructLayout(LayoutKind.Explicit)]
private struct DecomposedGuid
{
- [FieldOffset(00)] public Guid Value;
+ [FieldOffset(00)] public Guid? Value;
[FieldOffset(00)] public long Hi;
[FieldOffset(08)] public long Lo;
- public DecomposedGuid(Guid value) : this() => this.Value = value;
+ public DecomposedGuid(Guid? value) : this() => this.Value = value;
}
private static readonly char[] Base32Table =
@@ -58,12 +58,12 @@ namespace Umbraco.Cms.Core
/// that is case insensitive (base-64 is case sensitive).
/// Length must be 1-26, anything else becomes 26.
///
- public static string ToBase32String(Guid guid, int length = 26)
+ public static string ToBase32String(Guid? guid, int length = 26)
{
if (length <= 0 || length > 26)
length = 26;
- var bytes = guid.ToByteArray(); // a Guid is 128 bits ie 16 bytes
+ var bytes = guid?.ToByteArray(); // a Guid is 128 bits ie 16 bytes
// this could be optimized by making it unsafe,
// and fixing the table + bytes + chars (see Convert.ToBase64CharArray)
diff --git a/src/Umbraco.Core/IO/IMediaPathScheme.cs b/src/Umbraco.Core/IO/IMediaPathScheme.cs
index da9a06d1b1..61ab191d77 100644
--- a/src/Umbraco.Core/IO/IMediaPathScheme.cs
+++ b/src/Umbraco.Core/IO/IMediaPathScheme.cs
@@ -16,7 +16,7 @@ namespace Umbraco.Cms.Core.IO
/// The file name.
///
/// The filesystem-relative complete file path.
- string GetFilePath(MediaFileManager fileManager, Guid itemGuid, Guid propertyGuid, string filename);
+ string GetFilePath(MediaFileManager fileManager, Guid? itemGuid, Guid? propertyGuid, string filename);
///
/// Gets the directory that can be deleted when the file is deleted.
diff --git a/src/Umbraco.Core/IO/MediaFileManager.cs b/src/Umbraco.Core/IO/MediaFileManager.cs
index c3462913ff..01b6f09424 100644
--- a/src/Umbraco.Core/IO/MediaFileManager.cs
+++ b/src/Umbraco.Core/IO/MediaFileManager.cs
@@ -102,7 +102,7 @@ namespace Umbraco.Cms.Core.IO
/// The unique identifier of the property type owning the file.
/// The filesystem-relative path to the media file.
/// With the old media path scheme, this CREATES a new media path each time it is invoked.
- public string GetMediaPath(string? filename, Guid cuid, Guid puid)
+ public string GetMediaPath(string? filename, Guid? cuid, Guid? puid)
{
filename = Path.GetFileName(filename);
if (filename == null)
diff --git a/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs b/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs
index 5adc81276b..afbdb371bc 100644
--- a/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs
+++ b/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs
@@ -12,13 +12,13 @@ namespace Umbraco.Cms.Core.IO.MediaPathSchemes
public class CombinedGuidsMediaPathScheme : IMediaPathScheme
{
///
- public string GetFilePath(MediaFileManager fileManager, Guid itemGuid, Guid propertyGuid, string filename)
+ public string GetFilePath(MediaFileManager fileManager, Guid? itemGuid, Guid? propertyGuid, string filename)
{
// assumes that cuid and puid keys can be trusted - and that a single property type
// for a single content cannot store two different files with the same name
var combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
- var directory = HexEncoder.Encode(combinedGuid.ToByteArray()/*'/', 2, 4*/); // could use ext to fragment path eg 12/e4/f2/...
+ var directory = HexEncoder.Encode(combinedGuid?.ToByteArray()/*'/', 2, 4*/); // could use ext to fragment path eg 12/e4/f2/...
return Path.Combine(directory, filename).Replace('\\', '/');
}
diff --git a/src/Umbraco.Core/IO/MediaPathSchemes/TwoGuidsMediaPathScheme.cs b/src/Umbraco.Core/IO/MediaPathSchemes/TwoGuidsMediaPathScheme.cs
index 1ee821e3ed..49921b299a 100644
--- a/src/Umbraco.Core/IO/MediaPathSchemes/TwoGuidsMediaPathScheme.cs
+++ b/src/Umbraco.Core/IO/MediaPathSchemes/TwoGuidsMediaPathScheme.cs
@@ -12,9 +12,9 @@ namespace Umbraco.Cms.Core.IO.MediaPathSchemes
public class TwoGuidsMediaPathScheme : IMediaPathScheme
{
///
- public string GetFilePath(MediaFileManager fileManager, Guid itemGuid, Guid propertyGuid, string filename)
+ public string GetFilePath(MediaFileManager fileManager, Guid? itemGuid, Guid? propertyGuid, string filename)
{
- return Path.Combine(itemGuid.ToString("N"), propertyGuid.ToString("N"), filename).Replace('\\', '/');
+ return Path.Combine(itemGuid?.ToString("N"), propertyGuid?.ToString("N"), filename).Replace('\\', '/');
}
///
diff --git a/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs b/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs
index a3fe36bde9..feee7091c0 100644
--- a/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs
+++ b/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs
@@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.IO.MediaPathSchemes
private const int DirectoryLength = 8;
///
- public string GetFilePath(MediaFileManager fileManager, Guid itemGuid, Guid propertyGuid, string filename)
+ public string GetFilePath(MediaFileManager fileManager, Guid? itemGuid, Guid? propertyGuid, string filename)
{
var combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
var directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength);
diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentBaseSave.cs b/src/Umbraco.Core/Models/ContentEditing/ContentBaseSave.cs
index 294dc3386e..13d3c667e9 100644
--- a/src/Umbraco.Core/Models/ContentEditing/ContentBaseSave.cs
+++ b/src/Umbraco.Core/Models/ContentEditing/ContentBaseSave.cs
@@ -36,7 +36,7 @@ namespace Umbraco.Cms.Core.Models.ContentEditing
//These need explicit implementation because we are using internal models
///
[IgnoreDataMember]
- TPersisted? IContentSave.PersistedContent { get; set; }
+ TPersisted IContentSave.PersistedContent { get; set; }
//Non explicit internal getter so we don't need to explicitly cast in our own code
[IgnoreDataMember]
diff --git a/src/Umbraco.Core/Models/ContentEditing/ContentItemSave.cs b/src/Umbraco.Core/Models/ContentEditing/ContentItemSave.cs
index fb142048dd..acf2c5d789 100644
--- a/src/Umbraco.Core/Models/ContentEditing/ContentItemSave.cs
+++ b/src/Umbraco.Core/Models/ContentEditing/ContentItemSave.cs
@@ -50,11 +50,11 @@ namespace Umbraco.Cms.Core.Models.ContentEditing
//These need explicit implementation because we are using internal models
///
[IgnoreDataMember]
- IContent? IContentSave.PersistedContent { get; set; }
+ IContent IContentSave.PersistedContent { get; set; }
//Non explicit internal getter so we don't need to explicitly cast in our own code
[IgnoreDataMember]
- public IContent? PersistedContent
+ public IContent PersistedContent
{
get => ((IContentSave)this).PersistedContent;
set => ((IContentSave)this).PersistedContent = value;
diff --git a/src/Umbraco.Core/Models/ContentEditing/IContentSave.cs b/src/Umbraco.Core/Models/ContentEditing/IContentSave.cs
index a6c500e820..dfaf183479 100644
--- a/src/Umbraco.Core/Models/ContentEditing/IContentSave.cs
+++ b/src/Umbraco.Core/Models/ContentEditing/IContentSave.cs
@@ -18,6 +18,6 @@
///
/// This is not used for outgoing model information.
///
- TPersisted? PersistedContent { get; set; }
+ TPersisted PersistedContent { get; set; }
}
}
diff --git a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs
index 5fec2930b5..4ab39f1669 100644
--- a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs
+++ b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs
@@ -215,7 +215,7 @@ namespace Umbraco.Extensions
}
// sets the edited cultures on the content
- public static void SetCultureEdited(this IContent content, IEnumerable cultures)
+ public static void SetCultureEdited(this IContent content, IEnumerable? cultures)
{
if (cultures == null)
content.EditedCultures = null;
diff --git a/src/Umbraco.Core/Models/ContentScheduleCollection.cs b/src/Umbraco.Core/Models/ContentScheduleCollection.cs
index a2691a4c8e..42d1b07404 100644
--- a/src/Umbraco.Core/Models/ContentScheduleCollection.cs
+++ b/src/Umbraco.Core/Models/ContentScheduleCollection.cs
@@ -59,7 +59,7 @@ namespace Umbraco.Cms.Core.Models
///
///
/// true if successfully added, false if validation fails
- public bool Add(string culture, DateTime? releaseDate, DateTime? expireDate)
+ public bool Add(string? culture, DateTime? releaseDate, DateTime? expireDate)
{
if (culture == null) throw new ArgumentNullException(nameof(culture));
if (releaseDate.HasValue && expireDate.HasValue && releaseDate >= expireDate)
@@ -130,7 +130,7 @@ namespace Umbraco.Cms.Core.Models
///
///
/// If specified, will clear all entries with dates less than or equal to the value
- public void Clear(string culture, ContentScheduleAction action, DateTime? date = null)
+ public void Clear(string? culture, ContentScheduleAction action, DateTime? date = null)
{
if (!_schedule.TryGetValue(culture, out var schedules))
return;
@@ -176,7 +176,7 @@ namespace Umbraco.Cms.Core.Models
///
///
///
- public IEnumerable GetSchedule(string culture, ContentScheduleAction? action = null)
+ public IEnumerable GetSchedule(string? culture, ContentScheduleAction? action = null)
{
if (_schedule.TryGetValue(culture, out var changes))
return action == null ? changes.Values : changes.Values.Where(x => x.Action == action.Value);
diff --git a/src/Umbraco.Core/Models/CultureImpact.cs b/src/Umbraco.Core/Models/CultureImpact.cs
index dea741ab01..2f4364b61b 100644
--- a/src/Umbraco.Core/Models/CultureImpact.cs
+++ b/src/Umbraco.Core/Models/CultureImpact.cs
@@ -70,7 +70,7 @@ namespace Umbraco.Cms.Core.Models
///
/// The culture code.
/// A value indicating whether the culture is the default culture.
- public static CultureImpact Explicit(string culture, bool isDefault)
+ public static CultureImpact Explicit(string? culture, bool isDefault)
{
if (culture == null)
throw new ArgumentException("Culture is not explicit.");
diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index 07fd44397b..20e78816ae 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -43,7 +43,7 @@ namespace Umbraco.Cms.Core.Models
/// When is not null, throws if the content
/// type does not vary by culture.
///
- void SetCultureName(string? value, string culture);
+ void SetCultureName(string? value, string? culture);
///
/// Gets the name of the content item for a specified language.
diff --git a/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs b/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs
index 1a2ef5d508..fd52bc7805 100644
--- a/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs
+++ b/src/Umbraco.Core/Routing/IPublishedUrlProvider.cs
@@ -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/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs
index b3cb16e5f5..726c5b4435 100644
--- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs
+++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs
@@ -21,7 +21,7 @@ namespace Umbraco.Extensions
private static readonly Regex AnchorRegex = new Regex("", RegexOptions.Compiled);
- public static IEnumerable GetAnchorValuesFromRTEs(this IContentService contentService, int id, string culture = "*")
+ public static IEnumerable GetAnchorValuesFromRTEs(this IContentService contentService, int id, string? culture = "*")
{
var result = new List();
var content = contentService.GetById(id);
diff --git a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
index d9eb95a4be..36e9ac26c5 100644
--- a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
+++ b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
@@ -69,7 +69,7 @@ namespace Umbraco.Cms.Core.Services
#region Validation
- public Attempt ValidateComposition(TItem compo)
+ public Attempt ValidateComposition(TItem? compo)
{
try
{
@@ -86,7 +86,7 @@ namespace Umbraco.Cms.Core.Services
}
}
- protected void ValidateLocked(TItem compositionContentType)
+ protected void ValidateLocked(TItem? compositionContentType)
{
// performs business-level validation of the composition
// should ensure that it is absolutely safe to save the composition
@@ -449,8 +449,13 @@ namespace Umbraco.Cms.Core.Services
#region Save
- public void Save(TItem item, int userId = Cms.Core.Constants.Security.SuperUserId)
+ public void Save(TItem? item, int userId = Cms.Core.Constants.Security.SuperUserId)
{
+ if (item is null)
+ {
+ return;
+ }
+
using (IScope scope = ScopeProvider.CreateScope())
{
EventMessages eventMessages = EventMessagesFactory.Get();
@@ -957,13 +962,18 @@ namespace Umbraco.Cms.Core.Services
}
}
- public IEnumerable? GetContainers(TItem item)
+ public IEnumerable? GetContainers(TItem? item)
{
- var ancestorIds = item.Path.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries)
+ var ancestorIds = item?.Path.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries)
.Select(x => int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out var asInt) ? asInt : int.MinValue)
.Where(x => x != int.MinValue && x != item.Id)
.ToArray();
+ if (ancestorIds is null)
+ {
+ return null;
+ }
+
return GetContainers(ancestorIds);
}
diff --git a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs
index cd3c5273a1..6c30b24b67 100644
--- a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs
+++ b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs
@@ -45,7 +45,7 @@ namespace Umbraco.Extensions
/// Whether the composite content types should be applicable for an element type
///
public static ContentTypeAvailableCompositionsResults GetAvailableCompositeContentTypes(this IContentTypeService ctService,
- IContentTypeComposition source,
+ IContentTypeComposition? source,
IContentTypeComposition[] allContentTypes,
string[]? filterContentTypes = null,
string[]? filterPropertyTypes = null,
diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs
index 9899861a18..222f01d7e9 100644
--- a/src/Umbraco.Core/Services/IContentService.cs
+++ b/src/Umbraco.Core/Services/IContentService.cs
@@ -344,7 +344,7 @@ namespace Umbraco.Cms.Core.Services
///
/// Sorts documents.
///
- OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId);
+ OperationResult Sort(IEnumerable? ids, int userId = Constants.Security.SuperUserId);
#endregion
diff --git a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs
index 3835491cb4..17923c61da 100644
--- a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs
+++ b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs
@@ -56,13 +56,13 @@ namespace Umbraco.Cms.Core.Services
bool HasChildren(int id);
bool HasChildren(Guid id);
- void Save(TItem item, int userId = Constants.Security.SuperUserId);
+ void Save(TItem? item, int userId = Constants.Security.SuperUserId);
void Save(IEnumerable items, int userId = Constants.Security.SuperUserId);
void Delete(TItem item, int userId = Constants.Security.SuperUserId);
void Delete(IEnumerable item, int userId = Constants.Security.SuperUserId);
- Attempt ValidateComposition(TItem compo);
+ Attempt ValidateComposition(TItem? compo);
///
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
@@ -83,7 +83,7 @@ namespace Umbraco.Cms.Core.Services
EntityContainer? GetContainer(int containerId);
EntityContainer? GetContainer(Guid containerId);
IEnumerable? GetContainers(int[] containerIds);
- IEnumerable? GetContainers(TItem contentType);
+ IEnumerable? GetContainers(TItem? contentType);
IEnumerable? GetContainers(string folderName, int level);
Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId);
Attempt?> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId);
diff --git a/src/Umbraco.Core/Services/LocalizedTextServiceExtensions.cs b/src/Umbraco.Core/Services/LocalizedTextServiceExtensions.cs
index 4d926338f3..19ee3a4239 100644
--- a/src/Umbraco.Core/Services/LocalizedTextServiceExtensions.cs
+++ b/src/Umbraco.Core/Services/LocalizedTextServiceExtensions.cs
@@ -31,7 +31,7 @@ namespace Umbraco.Extensions
///
///
///
- public static string Localize(this ILocalizedTextService manager, string area, string alias, string?[]? tokens)
+ public static string Localize(this ILocalizedTextService manager, string? area, string alias, string?[]? tokens)
=> manager.Localize(area, alias, Thread.CurrentThread.CurrentUICulture, ConvertToDictionaryVars(tokens));
///
diff --git a/src/Umbraco.Core/Services/OperationResult.cs b/src/Umbraco.Core/Services/OperationResult.cs
index 9d4323553f..a69dc6ee12 100644
--- a/src/Umbraco.Core/Services/OperationResult.cs
+++ b/src/Umbraco.Core/Services/OperationResult.cs
@@ -20,7 +20,7 @@ namespace Umbraco.Cms.Core.Services
///
/// Initializes a new instance of the class.
///
- public OperationResult(TResultType result, EventMessages eventMessages)
+ public OperationResult(TResultType result, EventMessages? eventMessages)
{
Result = result;
EventMessages = eventMessages;
@@ -50,7 +50,7 @@ namespace Umbraco.Cms.Core.Services
///
/// Gets the event messages produced by the operation.
///
- public EventMessages EventMessages { get; }
+ public EventMessages? EventMessages { get; }
}
///
@@ -80,7 +80,7 @@ namespace Umbraco.Cms.Core.Services
///
/// Initializes a new instance of the class.
///
- public OperationResult(TResultType result, EventMessages eventMessages, TEntity entity)
+ public OperationResult(TResultType result, EventMessages? eventMessages, TEntity? entity)
: base(result, eventMessages)
{
Entity = entity;
diff --git a/src/Umbraco.Core/Services/PublishResult.cs b/src/Umbraco.Core/Services/PublishResult.cs
index ad5cae80ec..0ab820e7a6 100644
--- a/src/Umbraco.Core/Services/PublishResult.cs
+++ b/src/Umbraco.Core/Services/PublishResult.cs
@@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.Services
///
/// Initializes a new instance of the class.
///
- public PublishResult(PublishResultType resultType, EventMessages eventMessages, IContent content)
+ public PublishResult(PublishResultType resultType, EventMessages? eventMessages, IContent? content)
: base(resultType, eventMessages, content)
{ }
diff --git a/src/Umbraco.Core/Services/UserServiceExtensions.cs b/src/Umbraco.Core/Services/UserServiceExtensions.cs
index 227550e0d9..087e262101 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.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs
index f4b6ee62fd..8b6663051e 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs
@@ -258,7 +258,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
_textService = textService;
}
- public IEnumerable Validate(object? value, string valueType, object? dataTypeConfiguration)
+ public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration)
{
var blockConfig = (BlockListConfiguration?)dataTypeConfiguration;
if (blockConfig == null) yield break;
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ColorPickerConfigurationEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/ColorPickerConfigurationEditor.cs
index 67ac2c05e7..b143ecded9 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/ColorPickerConfigurationEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/ColorPickerConfigurationEditor.cs
@@ -154,7 +154,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
internal class ColorListValidator : IValueValidator
{
- public IEnumerable Validate(object? value, string valueType, object? dataTypeConfiguration)
+ public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration)
{
if (!(value is JArray json)) yield break;
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ComplexEditorValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/ComplexEditorValidator.cs
index d224e506c0..4e0694301f 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/ComplexEditorValidator.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/ComplexEditorValidator.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
///
///
///
- public IEnumerable Validate(object? value, string valueType, object? dataTypeConfiguration)
+ public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration)
{
var elementTypeValues = GetElementTypeValidation(value).ToList();
var rowResults = GetNestedValidationResults(elementTypeValues).ToList();
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs
index 573b4ac736..668986fbb5 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs
@@ -112,7 +112,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
}
- private string? ProcessFile(ContentPropertyFile file, object? dataTypeConfiguration, Guid cuid, Guid puid)
+ private string? ProcessFile(ContentPropertyFile file, object? dataTypeConfiguration, Guid? cuid, Guid? puid)
{
// process the file
// no file, invalid file, reject change
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/GridConfigurationEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/GridConfigurationEditor.cs
index 65367d039d..788a4ae496 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/GridConfigurationEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/GridConfigurationEditor.cs
@@ -24,7 +24,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
public class GridValidator : IValueValidator
{
- public IEnumerable Validate(object? rawValue, string valueType, object? dataTypeConfiguration)
+ public IEnumerable Validate(object? rawValue, string? valueType, object? dataTypeConfiguration)
{
if (rawValue == null)
yield break;
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs
index c9635ee121..8a13ded02f 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs
@@ -175,7 +175,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
return editorJson.ToString(Formatting.None);
}
- private string? ProcessFile(ContentPropertyFile file, Guid cuid, Guid puid)
+ private string? ProcessFile(ContentPropertyFile file, Guid? cuid, Guid? puid)
{
// process the file
// no file, invalid file, reject change
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/UploadFileTypeValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/UploadFileTypeValidator.cs
index 6e5c46e643..5f1ab43404 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/UploadFileTypeValidator.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/UploadFileTypeValidator.cs
@@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
contentSettings.OnChange(x => _contentSettings = x);
}
- public IEnumerable Validate(object? value, string valueType, object? dataTypeConfiguration)
+ public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration)
{
string? selectedFiles = null;
if (value is JObject jobject && jobject["selectedFiles"] is JToken jToken)
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs
index 1f74df8851..ab47886005 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/ValueListUniqueValueValidator.cs
@@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
///
public class ValueListUniqueValueValidator : IValueValidator
{
- public IEnumerable Validate(object? value, string valueType, object? dataTypeConfiguration)
+ public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration)
{
// the value we get should be a JArray
// [ { "value": , "sortOrder": 1 }, { ... }, ... ]
diff --git a/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResource.cs b/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResource.cs
index ae02db6d4f..cac7ac7917 100644
--- a/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResource.cs
+++ b/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResource.cs
@@ -16,7 +16,7 @@ namespace Umbraco.Cms.Web.BackOffice.Authorization
///
/// The content.
/// The permission to authorize.
- public ContentPermissionsResource(IContent content, char permissionToCheck)
+ public ContentPermissionsResource(IContent? content, char permissionToCheck)
{
PermissionsToCheck = new List { permissionToCheck };
Content = content;
diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
index 578d4e4b10..5e531c1eb4 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
@@ -126,7 +126,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
public IEnumerable GetByIds([FromQuery] int[] ids)
{
var foundContent = _contentService.GetByIds(ids);
- return foundContent.Select(MapToDisplay);
+ return foundContent.Select(MapToDisplay).WhereNotNull();
}
///
@@ -273,7 +273,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return display;
}
- public ActionResult GetBlueprintById(int id)
+ public ActionResult GetBlueprintById(int id)
{
var foundContent = _contentService.GetBlueprintById(id);
if (foundContent == null)
@@ -283,7 +283,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var content = MapToDisplay(foundContent);
- SetupBlueprint(content, foundContent);
+ if (content is not null)
+ {
+ SetupBlueprint(content, foundContent);
+ }
return content;
}
@@ -313,7 +316,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.ContentPermissionBrowseById)]
- public ActionResult GetById(int id)
+ public ActionResult GetById(int id)
{
var foundContent = GetObjectFromRequest(() => _contentService.GetById(id));
if (foundContent == null)
@@ -331,7 +334,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.ContentPermissionBrowseById)]
- public ActionResult GetById(Guid id)
+ public ActionResult GetById(Guid id)
{
var foundContent = GetObjectFromRequest(() => _contentService.GetById(id));
if (foundContent == null)
@@ -348,7 +351,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.ContentPermissionBrowseById)]
- public ActionResult GetById(Udi id)
+ public ActionResult GetById(Udi id)
{
var guidUdi = id as GuidUdi;
if (guidUdi != null)
@@ -365,7 +368,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
[OutgoingEditorModelEvent]
- public ActionResult GetEmpty(string contentTypeAlias, int parentId)
+ public ActionResult GetEmpty(string contentTypeAlias, int parentId)
{
var contentType = _contentTypeService.Get(contentTypeAlias);
if (contentType == null)
@@ -400,7 +403,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
[OutgoingEditorModelEvent]
- public ActionResult GetEmptyByKey(Guid contentTypeKey, int parentId)
+ public ActionResult GetEmptyByKey(Guid contentTypeKey, int parentId)
{
using (var scope = _scopeProvider.CreateScope())
{
@@ -417,11 +420,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- private ContentItemDisplay GetEmptyInner(IContentType contentType, int parentId)
+ private ContentItemDisplay? GetEmptyInner(IContentType contentType, int parentId)
{
var emptyContent = _contentService.Create("", parentId, contentType.Alias, _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
var mapped = MapToDisplay(emptyContent);
+ if (mapped is null)
+ {
+ return null;
+ }
return CleanContentItemDisplay(mapped);
}
@@ -694,8 +701,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return notificationModel;
}
- private bool EnsureUniqueName(string? name, IContent content, string modelName)
+ private bool EnsureUniqueName(string? name, IContent? content, string modelName)
{
+ if (content is null)
+ {
+ return false;
+ }
+
var existing = _contentService.GetBlueprintsForContentTypes(content.ContentTypeId);
if (existing?.Any(x => x.Name == name && x.Id != content.Id) ?? false)
{
@@ -711,13 +723,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[FileUploadCleanupFilter]
[ContentSaveValidation]
- public async Task>> PostSaveBlueprint([ModelBinder(typeof(BlueprintItemBinder))] ContentItemSave contentItem)
+ public async Task?>?> PostSaveBlueprint([ModelBinder(typeof(BlueprintItemBinder))] ContentItemSave contentItem)
{
var contentItemDisplay = await PostSaveInternal(
contentItem,
(content, _) =>
{
- if (!EnsureUniqueName(content.Name, content, "Name") || contentItem.PersistedContent is null)
+ if (!EnsureUniqueName(content?.Name, content, "Name") || contentItem.PersistedContent is null)
{
return OperationResult.Cancel(new EventMessages());
}
@@ -730,7 +742,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
content =>
{
var display = MapToDisplay(content);
- SetupBlueprint(display, content);
+ if (display is not null)
+ {
+ SetupBlueprint(display, content);
+ }
+
return display;
});
@@ -743,7 +759,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[FileUploadCleanupFilter]
[ContentSaveValidation]
[OutgoingEditorModelEvent]
- public async Task>> PostSave([ModelBinder(typeof(ContentItemBinder))] ContentItemSave contentItem)
+ public async Task?>> PostSave([ModelBinder(typeof(ContentItemBinder))] ContentItemSave contentItem)
{
var contentItemDisplay = await PostSaveInternal(
contentItem,
@@ -753,7 +769,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return contentItemDisplay;
}
- private async Task>> PostSaveInternal(ContentItemSave contentItem, Func saveMethod, Func> mapToDisplay)
+ private async Task?>> PostSaveInternal(ContentItemSave contentItem, Func? saveMethod, Func?> mapToDisplay)
where TVariant : ContentVariantDisplay
{
// Recent versions of IE/Edge may send in the full client side file path instead of just the file name.
@@ -864,17 +880,20 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
var variantErrors = ModelState.GetVariantsWithErrors(cultureForInvariantErrors);
- var validVariants = contentItem.Variants
- .Where(x => x.Save && !variantErrors.Contains((x.Culture, x.Segment)))
- .Select(x => (culture: x.Culture, segment: x.Segment));
-
- foreach (var (culture, segment) in validVariants)
+ if (variantErrors is not null)
{
- var variantName = GetVariantName(culture, segment);
+ var validVariants = contentItem.Variants
+ .Where(x => x.Save && !variantErrors.Contains((x.Culture, x.Segment)))
+ .Select(x => (culture: x.Culture, segment: x.Segment));
- AddSuccessNotification(notifications, culture, segment,
- _localizedTextService.Localize("speechBubbles", "editContentSendToPublish"),
- _localizedTextService.Localize("speechBubbles", "editVariantSendToPublishText", new[] { variantName }));
+ foreach (var (culture, segment) in validVariants)
+ {
+ var variantName = GetVariantName(culture, segment);
+
+ AddSuccessNotification(notifications, culture, segment,
+ _localizedTextService.Localize("speechBubbles", "editContentSendToPublish"),
+ _localizedTextService.Localize("speechBubbles", "editVariantSendToPublishText", new[] { variantName }));
+ }
}
}
else if (ModelState.IsValid)
@@ -935,11 +954,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var display = mapToDisplay(contentItem.PersistedContent);
//merge the tracked success messages with the outgoing model
- display.Notifications.AddRange(globalNotifications.Notifications);
- foreach (var v in display.Variants.Where(x => x.Language != null))
+ display?.Notifications.AddRange(globalNotifications.Notifications);
+ if (display?.Variants is not null)
{
- if (notifications.TryGetValue(v.Language.IsoCode, out var n))
- v.Notifications.AddRange(n.Notifications);
+ foreach (var v in display.Variants.Where(x => x.Language != null))
+ {
+ if (v.Language?.IsoCode is not null && notifications.TryGetValue(v.Language.IsoCode, out var n))
+ v.Notifications.AddRange(n.Notifications);
+ }
}
//lastly, if it is not valid, add the model state to the outgoing object and throw a 400
@@ -962,12 +984,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- display.PersistedContent = contentItem.PersistedContent;
+ if (display is not null)
+ {
+ display.PersistedContent = contentItem.PersistedContent;
+ }
return display;
}
- private void AddPublishStatusNotifications(IReadOnlyCollection publishStatus, SimpleNotificationModel globalNotifications, Dictionary variantNotifications, string[] successfulCultures)
+ private void AddPublishStatusNotifications(IReadOnlyCollection publishStatus, SimpleNotificationModel globalNotifications, Dictionary variantNotifications, string[]? successfulCultures)
{
//global notifications
AddMessageForPublishStatus(publishStatus, globalNotifications, successfulCultures);
@@ -1006,7 +1031,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//ensure the variant has all critical required data to be persisted
if (!RequiredForPersistenceAttribute.HasRequiredValuesForPersistence(variant))
{
- variantCriticalValidationErrors.Add(variant.Culture);
+ if (variant.Culture is not null)
+ {
+ variantCriticalValidationErrors.Add(variant.Culture);
+ }
+
//if there's no Name, it cannot be persisted at all reset the flags, this cannot be saved or published
variant.Save = variant.Publish = false;
@@ -1056,21 +1085,21 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// Method is used for normal Saving and Scheduled Publishing
///
- private void SaveAndNotify(ContentItemSave contentItem, Func saveMethod, int variantCount,
+ private void SaveAndNotify(ContentItemSave contentItem, Func? saveMethod, int variantCount,
Dictionary notifications, SimpleNotificationModel globalNotifications,
string savedContentHeaderLocalizationAlias, string invariantSavedLocalizationAlias, string variantSavedLocalizationAlias, string? cultureForInvariantErrors, ContentScheduleCollection? contentSchedule,
out bool wasCancelled)
{
- var saveResult = saveMethod(contentItem.PersistedContent, contentSchedule);
- wasCancelled = saveResult.Success == false && saveResult.Result == OperationResultType.FailedCancelledByEvent;
- if (saveResult.Success)
+ var saveResult = saveMethod?.Invoke(contentItem.PersistedContent, contentSchedule);
+ wasCancelled = saveResult?.Success == false && saveResult.Result == OperationResultType.FailedCancelledByEvent;
+ if (saveResult?.Success ?? false)
{
if (variantCount > 1)
{
var variantErrors = ModelState.GetVariantsWithErrors(cultureForInvariantErrors);
var savedWithoutErrors = contentItem.Variants
- .Where(x => x.Save && !variantErrors.Contains((x.Culture, x.Segment)))
+ .Where(x => x.Save && (!variantErrors?.Contains((x.Culture, x.Segment)) ?? false))
.Select(x => (culture: x.Culture, segment: x.Segment));
foreach (var (culture, segment) in savedWithoutErrors)
@@ -1098,7 +1127,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
private bool SaveSchedule(ContentItemSave contentItem, ContentScheduleCollection contentSchedule, SimpleNotificationModel globalNotifications)
{
- if (!contentItem.PersistedContent.ContentType.VariesByCulture())
+ if (!contentItem.PersistedContent?.ContentType.VariesByCulture() ?? false)
return SaveScheduleInvariant(contentItem, contentSchedule, globalNotifications);
else
return SaveScheduleVariant(contentItem, contentSchedule);
@@ -1192,7 +1221,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var nonMandatoryVariants = new List<(string culture, bool isPublished, List releaseDates)>();
foreach (var groupedSched in contentSchedule.FullSchedule.GroupBy(x => x.Culture))
{
- var isPublished = contentItem.PersistedContent.Published && contentItem.PersistedContent.IsCulturePublished(groupedSched.Key);
+ var isPublished = (contentItem.PersistedContent?.Published ?? false) && contentItem.PersistedContent.IsCulturePublished(groupedSched.Key);
var releaseDates = groupedSched.Where(x => x.Action == ContentScheduleAction.Release).Select(x => x.Date).ToList();
if (mandatoryCultures.Contains(groupedSched.Key, StringComparer.InvariantCultureIgnoreCase))
mandatoryVariants.Add((groupedSched.Key, isPublished, releaseDates));
@@ -1271,7 +1300,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// global notifications will be shown if all variant processing is successful and the save/publish dialog is closed, otherwise
/// variant specific notifications are used to show success messages in the save/publish dialog.
///
- private static void AddSuccessNotification(IDictionary notifications, string culture, string segment, string header, string msg)
+ private static void AddSuccessNotification(IDictionary notifications, string? culture, string? segment, string header, string msg)
{
//add the global notification (which will display globally if all variants are successfully processed)
notifications[string.Empty].AddSuccessNotification(header, msg);
@@ -1293,13 +1322,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return authorizationResult.Succeeded;
}
- private IEnumerable PublishBranchInternal(ContentItemSave contentItem, bool force, string cultureForInvariantErrors,
- out bool wasCancelled, out string[] successfulCultures)
+ private IEnumerable PublishBranchInternal(ContentItemSave contentItem, bool force, string? cultureForInvariantErrors,
+ out bool wasCancelled, out string[]? successfulCultures)
{
- if (!contentItem.PersistedContent.ContentType.VariesByCulture())
+ if (!contentItem.PersistedContent?.ContentType.VariesByCulture() ?? false)
{
//its invariant, proceed normally
- var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent, force, userId: _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent!, force, userId: _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
// TODO: Deal with multiple cancellations
wasCancelled = publishStatus.Any(x => x.Result == PublishResultType.FailedPublishCancelledByEvent);
successfulCultures = null; //must be null! this implies invariant
@@ -1325,7 +1354,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
foreach (var variant in contentItem.Variants)
{
- if (variantErrors.Contains((variant.Culture, variant.Segment)))
+ if (variantErrors?.Contains((variant.Culture, variant.Segment)) ?? false)
variant.Publish = false;
}
@@ -1334,16 +1363,16 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (canPublish)
{
//proceed to publish if all validation still succeeds
- var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent, force, culturesToPublish, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var publishStatus = _contentService.SaveAndPublishBranch(contentItem.PersistedContent!, force, culturesToPublish.WhereNotNull().ToArray(), _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
// TODO: Deal with multiple cancellations
wasCancelled = publishStatus.Any(x => x.Result == PublishResultType.FailedPublishCancelledByEvent);
- successfulCultures = contentItem.Variants.Where(x => x.Publish).Select(x => x.Culture).ToArray();
+ successfulCultures = contentItem.Variants.Where(x => x.Publish).Select(x => x.Culture).WhereNotNull().ToArray();
return publishStatus;
}
else
{
//can only save
- var saveResult = _contentService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var saveResult = _contentService.Save(contentItem.PersistedContent!, _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
var publishStatus = new[]
{
new PublishResult(PublishResultType.FailedPublishMandatoryCultureMissing, null, contentItem.PersistedContent)
@@ -1366,12 +1395,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// If this is a culture variant than we need to do some validation, if it's not we'll publish as normal
///
- private PublishResult PublishInternal(ContentItemSave contentItem, string defaultCulture, string cultureForInvariantErrors, out bool wasCancelled, out string[] successfulCultures)
+ private PublishResult PublishInternal(ContentItemSave contentItem, string? defaultCulture, string? cultureForInvariantErrors, out bool wasCancelled, out string[]? successfulCultures)
{
- if (!contentItem.PersistedContent.ContentType.VariesByCulture())
+ if (!contentItem.PersistedContent?.ContentType.VariesByCulture() ?? false)
{
//its invariant, proceed normally
- var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent, userId: _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent!, userId: _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
wasCancelled = publishStatus.Result == PublishResultType.FailedPublishCancelledByEvent;
successfulCultures = null; //must be null! this implies invariant
return publishStatus;
@@ -1398,25 +1427,25 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//It is a requirement that this is performed AFTER ValidatePublishingMandatoryLanguages.
foreach (var variant in contentItem.Variants)
{
- if (variantErrors.Contains((variant.Culture, variant.Segment)))
+ if (variantErrors?.Contains((variant.Culture, variant.Segment)) ?? false)
variant.Publish = false;
}
//At this stage all variants might have failed validation which means there are no cultures flagged for publishing!
- var culturesToPublish = variants.Where(x => x.Publish).Select(x => x.Culture).ToArray();
+ var culturesToPublish = variants.Where(x => x.Publish).Select(x => x.Culture).WhereNotNull().ToArray();
canPublish = canPublish && culturesToPublish.Length > 0;
if (canPublish)
{
//try to publish all the values on the model - this will generally only fail if someone is tampering with the request
//since there's no reason variant rules would be violated in normal cases.
- canPublish = PublishCulture(contentItem.PersistedContent, variants, defaultCulture);
+ canPublish = PublishCulture(contentItem.PersistedContent!, variants, defaultCulture);
}
if (canPublish)
{
//proceed to publish if all validation still succeeds
- var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent, culturesToPublish, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var publishStatus = _contentService.SaveAndPublish(contentItem.PersistedContent!, culturesToPublish, _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
wasCancelled = publishStatus.Result == PublishResultType.FailedPublishCancelledByEvent;
successfulCultures = culturesToPublish;
@@ -1425,7 +1454,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
else
{
//can only save
- var saveResult = _contentService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var saveResult = _contentService.Save(contentItem.PersistedContent!, _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
var publishStatus = new PublishResult(PublishResultType.FailedPublishMandatoryCultureMissing, null, contentItem.PersistedContent);
wasCancelled = saveResult.Result == OperationResultType.FailedCancelledByEvent;
successfulCultures = Array.Empty();
@@ -1433,7 +1462,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- private void AddDomainWarnings(IEnumerable publishResults, string[] culturesPublished,
+ private void AddDomainWarnings(IEnumerable publishResults, string[]? culturesPublished,
SimpleNotificationModel globalNotifications)
{
foreach (PublishResult publishResult in publishResults)
@@ -1452,7 +1481,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- internal void AddDomainWarnings(IContent persistedContent, string[] culturesPublished, SimpleNotificationModel globalNotifications)
+ internal void AddDomainWarnings(IContent? persistedContent, string[]? culturesPublished, SimpleNotificationModel globalNotifications)
{
// Don't try to verify if no cultures were published
if (culturesPublished is null)
@@ -1468,35 +1497,40 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
// If more than a single culture is published we need to verify that there's a domain registered for each published culture
- var assignedDomains = _domainService.GetAssignedDomains(persistedContent.Id, true).ToHashSet();
- // We also have to check all of the ancestors, if any of those has the appropriate culture assigned we don't need to warn
- foreach (var ancestorID in persistedContent.GetAncestorIds())
+ var assignedDomains = persistedContent is null ? null : _domainService.GetAssignedDomains(persistedContent.Id, true)?.ToHashSet();
+
+ var ancestorIds = persistedContent?.GetAncestorIds();
+ if (ancestorIds is not null && assignedDomains is not null)
{
- assignedDomains.UnionWith(_domainService.GetAssignedDomains(ancestorID, true));
+ // We also have to check all of the ancestors, if any of those has the appropriate culture assigned we don't need to warn
+ foreach (var ancestorID in ancestorIds)
+ {
+ assignedDomains.UnionWith(_domainService.GetAssignedDomains(ancestorID, true) ?? Enumerable.Empty());
+ }
}
// No domains at all, add a warning, to add domains.
- if (assignedDomains.Count == 0)
+ if (assignedDomains is null || assignedDomains.Count == 0)
{
globalNotifications.AddWarningNotification(
_localizedTextService.Localize("auditTrails", "publish"),
_localizedTextService.Localize("speechBubbles", "publishWithNoDomains"));
_logger.LogWarning("The root node {RootNodeName} was published with multiple cultures, but no domains are configured, this will cause routing and caching issues, please register domains for: {Cultures}",
- persistedContent.Name, string.Join(", ", publishedCultures));
+ persistedContent?.Name, string.Join(", ", publishedCultures));
return;
}
// If there is some domains, verify that there's a domain for each of the published cultures
foreach (var culture in culturesPublished
- .Where(culture => assignedDomains.Any(x => x.LanguageIsoCode.Equals(culture, StringComparison.OrdinalIgnoreCase)) is false))
+ .Where(culture => assignedDomains.Any(x => x.LanguageIsoCode?.Equals(culture, StringComparison.OrdinalIgnoreCase) ?? false) is false))
{
globalNotifications.AddWarningNotification(
_localizedTextService.Localize("auditTrails", "publish"),
_localizedTextService.Localize("speechBubbles", "publishWithMissingDomain", new []{culture}));
_logger.LogWarning("The root node {RootNodeName} was published in culture {Culture}, but there's no domain configured for it, this will cause routing and caching issues, please register a domain for it",
- persistedContent.Name, culture);
+ persistedContent?.Name, culture);
}
}
@@ -1510,7 +1544,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
private bool ValidatePublishingMandatoryLanguages(
- IReadOnlyCollection<(string culture, string segment)> variantsWithValidationErrors,
+ IReadOnlyCollection<(string? culture, string? segment)>? variantsWithValidationErrors,
ContentItemSave contentItem,
IReadOnlyCollection variants,
IReadOnlyList mandatoryCultures,
@@ -1525,15 +1559,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var mandatoryVariant = variants.First(x => x.Culture.InvariantEquals(culture));
- var isPublished = contentItem.PersistedContent.Published && contentItem.PersistedContent.IsCulturePublished(culture);
+ var isPublished = (contentItem.PersistedContent?.Published ?? false) && contentItem.PersistedContent.IsCulturePublished(culture);
var isPublishing = isPublished || publishingCheck(mandatoryVariant);
- var isValid = !variantsWithValidationErrors.Select(v => v.culture).InvariantContains(culture);
+ var isValid = !variantsWithValidationErrors?.Select(v => v.culture!).InvariantContains(culture) ?? false;
result.Add((mandatoryVariant, isPublished || isPublishing, isValid));
}
//iterate over the results by invalid first
- string firstInvalidMandatoryCulture = null;
+ string? firstInvalidMandatoryCulture = null;
foreach (var r in result.OrderBy(x => x.isValid))
{
if (!r.isValid)
@@ -1571,7 +1605,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// This would generally never fail unless someone is tampering with the request
///
- private bool PublishCulture(IContent persistentContent, IEnumerable cultureVariants, string defaultCulture)
+ private bool PublishCulture(IContent persistentContent, IEnumerable cultureVariants, string? defaultCulture)
{
foreach (var variant in cultureVariants.Where(x => x.Publish))
{
@@ -1587,26 +1621,28 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return true;
}
- private IEnumerable GetPublishedCulturesFromAncestors(IContent content)
+ private IEnumerable GetPublishedCulturesFromAncestors(IContent? content)
{
- if (content.ParentId == -1)
+ if (content?.ParentId == -1)
{
return content.PublishedCultures;
}
HashSet publishedCultures = new ();
- publishedCultures.UnionWith(content.PublishedCultures);
+ publishedCultures.UnionWith(content?.PublishedCultures ?? Enumerable.Empty());
- IEnumerable ancestorIds = content.GetAncestorIds();
+ IEnumerable? ancestorIds = content?.GetAncestorIds();
- foreach (var id in ancestorIds)
+ if (ancestorIds is not null)
{
- IEnumerable cultures = _contentService.GetById(id).PublishedCultures;
- publishedCultures.UnionWith(cultures);
+ foreach (var id in ancestorIds)
+ {
+ IEnumerable? cultures = _contentService.GetById(id)?.PublishedCultures;
+ publishedCultures.UnionWith(cultures ?? Enumerable.Empty());
+ }
}
return publishedCultures;
-
}
///
/// Adds a generic culture error for use in displaying the culture validation error in the save/publish/etc... dialogs
@@ -1617,7 +1653,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// The culture used in the localization message, null by default which means will be used.
///
- private void AddVariantValidationError(string culture, string segment, string localizationArea,string localizationAlias, string cultureToken = null)
+ private void AddVariantValidationError(string? culture, string? segment, string localizationArea,string localizationAlias, string? cultureToken = null)
{
var cultureToUse = cultureToken ?? culture;
var variantName = GetVariantName(cultureToUse, segment);
@@ -1633,7 +1669,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// Culture
/// Segment
///
- private string GetVariantName(string culture, string segment)
+ private string GetVariantName(string? culture, string? segment)
{
if (culture.IsNullOrWhiteSpace() && segment.IsNullOrWhiteSpace())
{
@@ -1667,7 +1703,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return HandleContentNotFound(id);
}
- var publishResult = _contentService.SaveAndPublish(foundContent, userId: _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
+ var publishResult = _contentService.SaveAndPublish(foundContent, userId: _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? 0);
if (publishResult.Success == false)
{
var notificationModel = new SimpleNotificationModel();
@@ -1719,7 +1755,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//if the current item is in the recycle bin
if (foundContent.Trashed == false)
{
- var moveResult = _contentService.MoveToRecycleBin(foundContent, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
+ var moveResult = _contentService.MoveToRecycleBin(foundContent, _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
if (moveResult.Success == false)
{
return ValidationProblem();
@@ -1727,7 +1763,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
else
{
- var deleteResult = _contentService.Delete(foundContent, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
+ var deleteResult = _contentService.Delete(foundContent, _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
if (deleteResult.Success == false)
{
return ValidationProblem();
@@ -1749,7 +1785,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[Authorize(Policy = AuthorizationPolicies.ContentPermissionEmptyRecycleBin)]
public IActionResult EmptyRecycleBin()
{
- _contentService.EmptyRecycleBin(_backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? -1);
+ _contentService.EmptyRecycleBin(_backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
return Ok(_localizedTextService.Localize("defaultdialogs", "recycleBinIsEmpty"));
}
@@ -1767,7 +1803,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
//if there's nothing to sort just return ok
- if (sorted.IdSortOrder.Length == 0)
+ if (sorted.IdSortOrder?.Length == 0)
{
return Ok();
}
@@ -1783,7 +1819,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
try
{
// Save content with new sort order and update content xml in db accordingly
- var sortResult = _contentService.Sort(sorted.IdSortOrder, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
+ var sortResult = _contentService.Sort(sorted.IdSortOrder, _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
if (!sortResult.Success)
{
_logger.LogWarning("Content sorting failed, this was probably caused by an event being cancelled");
@@ -1805,7 +1841,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public async Task PostMove(MoveOrCopy move)
+ public async Task PostMove(MoveOrCopy move)
{
// Authorize...
var resource = new ContentPermissionsResource(_contentService.GetById(move.ParentId), ActionMove.ActionLetter);
@@ -1822,7 +1858,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
var toMove = toMoveResult.Value;
- _contentService.Move(toMove, move.ParentId, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
+ if (toMove is null)
+ {
+ return null;
+ }
+ _contentService.Move(toMove, move.ParentId, _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
return Content(toMove.Path, MediaTypeNames.Text.Plain, Encoding.UTF8);
}
@@ -1832,7 +1872,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public async Task> PostCopy(MoveOrCopy copy)
+ public async Task?> PostCopy(MoveOrCopy copy)
{
// Authorize...
var resource = new ContentPermissionsResource(_contentService.GetById(copy.ParentId), ActionCopy.ActionLetter);
@@ -1848,7 +1888,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return toCopyResult.Result;
}
var toCopy = toCopyResult.Value;
- var c = _contentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal, copy.Recursive, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
+ if (toCopy is null)
+ {
+ return null;
+ }
+
+ var c = _contentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal, copy.Recursive, _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
+
+ if (c is null)
+ {
+ return null;
+ }
return Content(c.Path, MediaTypeNames.Text.Plain, Encoding.UTF8);
}
@@ -1859,7 +1909,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// The content and variants to unpublish
///
[OutgoingEditorModelEvent]
- public async Task> PostUnpublish(UnpublishContent model)
+ public async Task> PostUnpublish(UnpublishContent model)
{
var foundContent = _contentService.GetById(model.Id);
@@ -1877,10 +1927,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
var languageCount = _allLangs.Value.Count();
- if (model.Cultures.Length == 0 || model.Cultures.Length == languageCount)
+ if (model.Cultures?.Length == 0 || model.Cultures?.Length == languageCount)
{
//this means that the entire content item will be unpublished
- var unpublishResult = _contentService.Unpublish(foundContent, userId: _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
+ var unpublishResult = _contentService.Unpublish(foundContent, userId: _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
var content = MapToDisplayWithSchedule(foundContent);
@@ -1891,7 +1941,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
else
{
- content.AddSuccessNotification(
+ content?.AddSuccessNotification(
_localizedTextService.Localize("content", "unpublish"),
_localizedTextService.Localize("speechBubbles", "contentUnpublished"));
return content;
@@ -1901,14 +1951,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
//we only want to unpublish some of the variants
var results = new Dictionary();
- foreach (var c in model.Cultures)
+ if (model.Cultures is not null)
{
- var result = _contentService.Unpublish(foundContent, culture: c, userId: _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().Result ?? 0);
- results[c] = result;
- if (result.Result == PublishResultType.SuccessUnpublishMandatoryCulture)
+ foreach (var c in model.Cultures)
{
- //if this happens, it means they are all unpublished, we don't need to continue
- break;
+ var result = _contentService.Unpublish(foundContent, culture: c, userId: _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1);
+ results[c] = result;
+ if (result.Result == PublishResultType.SuccessUnpublishMandatoryCulture)
+ {
+ //if this happens, it means they are all unpublished, we don't need to continue
+ break;
+ }
}
}
@@ -1917,7 +1970,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//check for this status and return the correct message
if (results.Any(x => x.Value.Result == PublishResultType.SuccessUnpublishMandatoryCulture))
{
- content.AddSuccessNotification(
+ content?.AddSuccessNotification(
_localizedTextService.Localize("content", "unpublish"),
_localizedTextService.Localize("speechBubbles", "contentMandatoryCultureUnpublished"));
return content;
@@ -1926,7 +1979,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//otherwise add a message for each one unpublished
foreach (var r in results)
{
- content.AddSuccessNotification(
+ content?.AddSuccessNotification(
_localizedTextService.Localize("conten", "unpublish"),
_localizedTextService.Localize("speechBubbles", "contentCultureUnpublished", new[] { _allLangs.Value[r.Key].CultureName }));
}
@@ -1938,9 +1991,9 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
public ContentDomainsAndCulture GetCultureAndDomains(int id)
{
- var nodeDomains = _domainService.GetAssignedDomains(id, true).ToArray();
- var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
- var domains = nodeDomains.Where(d => !d.IsWildcard).Select(d => new DomainDisplay(d.DomainName, d.LanguageId.GetValueOrDefault(0)));
+ var nodeDomains = _domainService.GetAssignedDomains(id, true)?.ToArray();
+ var wildcard = nodeDomains?.FirstOrDefault(d => d.IsWildcard);
+ var domains = nodeDomains?.Where(d => !d.IsWildcard).Select(d => new DomainDisplay(d.DomainName, d.LanguageId.GetValueOrDefault(0)));
return new ContentDomainsAndCulture
{
Domains = domains,
@@ -1951,15 +2004,18 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[HttpPost]
public ActionResult PostSaveLanguageAndDomains(DomainSave model)
{
- foreach (var domain in model.Domains)
+ if (model.Domains is not null)
{
- try
+ foreach (var domain in model.Domains)
{
- var uri = DomainUtilities.ParseUriFromDomainName(domain.Name, new Uri(Request.GetEncodedUrl()));
- }
- catch (UriFormatException)
- {
- return ValidationProblem(_localizedTextService.Localize("assignDomain", "invalidDomain"));
+ try
+ {
+ var uri = DomainUtilities.ParseUriFromDomainName(domain.Name, new Uri(Request.GetEncodedUrl()));
+ }
+ catch (UriFormatException)
+ {
+ return ValidationProblem(_localizedTextService.Localize("assignDomain", "invalidDomain"));
+ }
}
}
@@ -1971,17 +2027,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return NotFound("There is no content node with id {model.NodeId}.");
}
- var permission = _userService.GetPermissions(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, node.Path);
+ var permission = _userService.GetPermissions(_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, node.Path);
- if (permission.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) == false)
+ if (permission?.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) == false)
{
HttpContext.SetReasonPhrase("Permission Denied.");
return BadRequest("You do not have permission to assign domains on that node.");
}
model.Valid = true;
- var domains = _domainService.GetAssignedDomains(model.NodeId, true).ToArray();
+ var domains = _domainService.GetAssignedDomains(model.NodeId, true)?.ToArray();
var languages = _localizationService.GetAllLanguages().ToArray();
var language = model.Language > 0 ? languages.FirstOrDefault(l => l.Id == model.Language) : null;
@@ -1989,7 +2045,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (language != null)
{
// yet there is a race condition here...
- var wildcard = domains.FirstOrDefault(d => d.IsWildcard);
+ var wildcard = domains?.FirstOrDefault(d => d.IsWildcard);
if (wildcard != null)
{
wildcard.LanguageId = language.Id;
@@ -2006,13 +2062,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var saveAttempt = _domainService.Save(wildcard);
if (saveAttempt == false)
{
- HttpContext.SetReasonPhrase(saveAttempt.Result.Result.ToString());
+ HttpContext.SetReasonPhrase(saveAttempt.Result?.Result.ToString());
return BadRequest("Saving domain failed");
}
}
else
{
- var wildcard = domains.FirstOrDefault(d => d.IsWildcard);
+ var wildcard = domains?.FirstOrDefault(d => d.IsWildcard);
if (wildcard != null)
{
_domainService.Delete(wildcard);
@@ -2021,7 +2077,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// process domains
// delete every (non-wildcard) domain, that exists in the DB yet is not in the model
- foreach (var domain in domains.Where(d => d.IsWildcard == false && model.Domains.All(m => m.Name.InvariantEquals(d.DomainName) == false)))
+ foreach (var domain in domains?.Where(d => d.IsWildcard == false && (model.Domains?.All(m => m.Name.InvariantEquals(d.DomainName) == false) ?? false)) ?? Array.Empty())
{
_domainService.Delete(domain);
}
@@ -2029,7 +2085,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var names = new List();
// create or update domains in the model
- foreach (var domainModel in model.Domains.Where(m => string.IsNullOrWhiteSpace(m.Name) == false))
+ foreach (var domainModel in model.Domains?.Where(m => string.IsNullOrWhiteSpace(m.Name) == false) ?? Array.Empty())
{
language = languages.FirstOrDefault(l => l.Id == domainModel.Lang);
if (language == null)
@@ -2044,7 +2100,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
continue;
}
names.Add(name);
- var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name));
+ var domain = domains?.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name));
if (domain != null)
{
domain.LanguageId = language.Id;
@@ -2054,14 +2110,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
domainModel.Duplicate = true;
var xdomain = _domainService.GetByName(domainModel.Name);
- var xrcid = xdomain.RootContentId;
+ var xrcid = xdomain?.RootContentId;
if (xrcid.HasValue)
{
var xcontent = _contentService.GetById(xrcid.Value);
var xnames = new List();
while (xcontent != null)
{
- xnames.Add(xcontent.Name);
+ if (xcontent.Name is not null)
+ {
+ xnames.Add(xcontent.Name);
+ }
if (xcontent.ParentId < -1)
xnames.Add("Recycle Bin");
xcontent = _contentService.GetParent(xcontent);
@@ -2081,13 +2140,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var saveAttempt = _domainService.Save(newDomain);
if (saveAttempt == false)
{
- HttpContext.SetReasonPhrase(saveAttempt.Result.Result.ToString());
+ HttpContext.SetReasonPhrase(saveAttempt.Result?.Result.ToString());
return BadRequest("Saving new domain failed");
}
}
}
- model.Valid = model.Domains.All(m => m.Duplicate == false);
+ model.Valid = model.Domains?.All(m => m.Duplicate == false) ?? false;
return model;
}
@@ -2100,17 +2159,20 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// This is required to wire up the validation in the save/publish dialog
///
- private void HandleInvalidModelState(ContentItemDisplay display, string cultureForInvariantErrors)
+ private void HandleInvalidModelState(ContentItemDisplay? display, string? cultureForInvariantErrors)
where TVariant : ContentVariantDisplay
{
- if (!ModelState.IsValid && display.Variants.Count() > 1)
+ if (!ModelState.IsValid && display?.Variants?.Count() > 1)
{
//Add any culture specific errors here
var variantErrors = ModelState.GetVariantsWithErrors(cultureForInvariantErrors);
- foreach (var (culture, segment) in variantErrors)
+ if (variantErrors is not null)
{
- AddVariantValidationError(culture, segment, "speechBubbles", "contentCultureValidationError");
+ foreach (var (culture, segment) in variantErrors)
+ {
+ AddVariantValidationError(culture, segment, "speechBubbles", "contentCultureValidationError");
+ }
}
}
}
@@ -2122,10 +2184,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
private void MapValuesForPersistence(ContentItemSave contentSave)
{
// inline method to determine the culture and segment to persist the property
- (string culture, string segment) PropertyCultureAndSegment(IProperty property, ContentVariantSave variant)
+ (string? culture, string? segment) PropertyCultureAndSegment(IProperty? property, ContentVariantSave variant)
{
- var culture = property.PropertyType.VariesByCulture() ? variant.Culture : null;
- var segment = property.PropertyType.VariesBySegment() ? variant.Segment : null;
+ var culture = property?.PropertyType.VariesByCulture() ?? false ? variant.Culture : null;
+ var segment = property?.PropertyType.VariesBySegment() ?? false ? variant.Segment : null;
return (culture, segment);
}
@@ -2144,7 +2206,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// Don't update the name if it is empty
if (!variant.Name.IsNullOrWhiteSpace())
{
- if (contentSave.PersistedContent.ContentType.VariesByCulture())
+ if (contentSave.PersistedContent?.ContentType.VariesByCulture() ?? false)
{
if (variant.Culture.IsNullOrWhiteSpace())
{
@@ -2154,14 +2216,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
contentSave.PersistedContent.SetCultureName(variant.Name, variant.Culture);
// If the variant culture is the default culture we also want to update the name on the Content itself.
- if (variant.Culture.Equals(defaultCulture, StringComparison.InvariantCultureIgnoreCase))
+ if (variant.Culture?.Equals(defaultCulture, StringComparison.InvariantCultureIgnoreCase) ?? false)
{
contentSave.PersistedContent.Name = variant.Name;
}
}
else
{
- contentSave.PersistedContent.Name = variant.Name;
+ if (contentSave.PersistedContent is not null)
+ {
+ contentSave.PersistedContent.Name = variant.Name;
+ }
}
}
@@ -2172,8 +2237,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
? variant.PropertyCollectionDto
: new ContentPropertyCollectionDto
{
- Properties = variant.PropertyCollectionDto.Properties.Where(
- x => !x.Culture.IsNullOrWhiteSpace() || !x.Segment.IsNullOrWhiteSpace()),
+ Properties = variant.PropertyCollectionDto?.Properties.Where(
+ x => !x.Culture.IsNullOrWhiteSpace() || !x.Segment.IsNullOrWhiteSpace()) ?? Enumerable.Empty(),
};
// for each variant, map the property values
@@ -2184,13 +2249,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
// Get property value
(var culture, var segment) = PropertyCultureAndSegment(property, variant);
- return property.GetValue(culture, segment);
+ return property?.GetValue(culture, segment);
},
(save, property, v) =>
{
// Set property value
(var culture, var segment) = PropertyCultureAndSegment(property, variant);
- property.SetValue(v, culture, segment);
+ property?.SetValue(v, culture, segment);
},
variant.Culture);
@@ -2198,28 +2263,28 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
// Map IsDirty cultures to edited cultures, to make it easier to verify changes on specific variants on Saving and Saved events.
- IEnumerable editedCultures = contentSave.PersistedContent.CultureInfos.Values
+ IEnumerable? editedCultures = contentSave.PersistedContent?.CultureInfos?.Values
.Where(x => x.IsDirty())
.Select(x => x.Culture);
- contentSave.PersistedContent.SetCultureEdited(editedCultures);
+ contentSave.PersistedContent?.SetCultureEdited(editedCultures);
// handle template
if (string.IsNullOrWhiteSpace(contentSave.TemplateAlias)) // cleared: clear if not already null
{
- if (contentSave.PersistedContent.TemplateId != null)
+ if (contentSave.PersistedContent?.TemplateId != null)
{
contentSave.PersistedContent.TemplateId = null;
}
}
else // set: update if different
{
- ITemplate template = _fileService.GetTemplate(contentSave.TemplateAlias);
+ ITemplate? template = _fileService.GetTemplate(contentSave.TemplateAlias);
if (template is null)
{
// ModelState.AddModelError("Template", "No template exists with the specified alias: " + contentItem.TemplateAlias);
_logger.LogWarning("No template exists with the specified alias: {TemplateAlias}", contentSave.TemplateAlias);
}
- else if (template.Id != contentSave.PersistedContent.TemplateId)
+ else if (contentSave.PersistedContent is not null && template.Id != contentSave.PersistedContent.TemplateId)
{
contentSave.PersistedContent.TemplateId = template.Id;
}
@@ -2263,7 +2328,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var parentContentType = _contentTypeService.Get(parent.ContentTypeId);
//check if the item is allowed under this one
- if (parentContentType.AllowedContentTypes.Select(x => x.Id).ToArray()
+ if (parentContentType?.AllowedContentTypes?.Select(x => x.Id).ToArray()
.Any(x => x.Value == toMove.ContentType.Id) == false)
{
return ValidationProblem(
@@ -2289,7 +2354,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// This is null when dealing with invariant content, else it's the cultures that were successfully published
///
- private void AddMessageForPublishStatus(IReadOnlyCollection statuses, INotificationModel display, string[] successfulCultures = null)
+ private void AddMessageForPublishStatus(IReadOnlyCollection statuses, INotificationModel display, string[]? successfulCultures = null)
{
var totalStatusCount = statuses.Count();
@@ -2389,7 +2454,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case PublishResultType.FailedPublishPathNotPublished:
{
//TODO: This doesn't take into account variations with the successfulCultures param
- var names = string.Join(", ", status.Select(x => $"'{x.Content.Name}'"));
+ var names = string.Join(", ", status.Select(x => $"'{x.Content?.Name}'"));
display.AddWarningNotification(
_localizedTextService.Localize(null,"publish"),
_localizedTextService.Localize("publish", "contentPublishedFailedByParent",
@@ -2399,14 +2464,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case PublishResultType.FailedPublishCancelledByEvent:
{
//TODO: This doesn't take into account variations with the successfulCultures param
- var names = string.Join(", ", status.Select(x => $"'{x.Content.Name}'"));
+ var names = string.Join(", ", status.Select(x => $"'{x.Content?.Name}'"));
AddCancelMessage(display, "publish","contentPublishedFailedByEvent", messageParams: new[] { names });
}
break;
case PublishResultType.FailedPublishAwaitingRelease:
{
//TODO: This doesn't take into account variations with the successfulCultures param
- var names = string.Join(", ", status.Select(x => $"'{x.Content.Name}'"));
+ var names = string.Join(", ", status.Select(x => $"'{x.Content?.Name}'"));
display.AddWarningNotification(
_localizedTextService.Localize(null,"publish"),
_localizedTextService.Localize("publish", "contentPublishedFailedAwaitingRelease",
@@ -2416,7 +2481,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case PublishResultType.FailedPublishHasExpired:
{
//TODO: This doesn't take into account variations with the successfulCultures param
- var names = string.Join(", ", status.Select(x => $"'{x.Content.Name}'"));
+ var names = string.Join(", ", status.Select(x => $"'{x.Content?.Name}'"));
display.AddWarningNotification(
_localizedTextService.Localize(null,"publish"),
_localizedTextService.Localize("publish", "contentPublishedFailedExpired",
@@ -2426,7 +2491,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case PublishResultType.FailedPublishIsTrashed:
{
//TODO: This doesn't take into account variations with the successfulCultures param
- var names = string.Join(", ", status.Select(x => $"'{x.Content.Name}'"));
+ var names = string.Join(", ", status.Select(x => $"'{x.Content?.Name}'"));
display.AddWarningNotification(
_localizedTextService.Localize(null,"publish"),
_localizedTextService.Localize("publish", "contentPublishedFailedIsTrashed",
@@ -2437,7 +2502,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
if (successfulCultures == null)
{
- var names = string.Join(", ", status.Select(x => $"'{x.Content.Name}'"));
+ var names = string.Join(", ", status.Select(x => $"'{x.Content?.Name}'"));
display.AddWarningNotification(
_localizedTextService.Localize(null,"publish"),
_localizedTextService.Localize("publish", "contentPublishedFailedInvalid",
@@ -2447,7 +2512,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
foreach (var c in successfulCultures)
{
- var names = string.Join(", ", status.Select(x => $"'{(x.Content.ContentType.VariesByCulture() ? x.Content.GetCultureName(c) : x.Content.Name)}'"));
+ var names = string.Join(", ", status.Select(x => $"'{(x.Content?.ContentType.VariesByCulture() ?? false ? x.Content.GetCultureName(c) : x.Content?.Name)}'"));
display.AddWarningNotification(
_localizedTextService.Localize(null,"publish"),
_localizedTextService.Localize("publish", "contentPublishedFailedInvalid",
@@ -2472,20 +2537,30 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- private ContentItemDisplay MapToDisplay(IContent? content) =>
+ private ContentItemDisplay? MapToDisplay(IContent? content) =>
MapToDisplay(content, context =>
{
- context.Items["CurrentUser"] = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
+ context.Items["CurrentUser"] = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser;
});
- private ContentItemDisplayWithSchedule MapToDisplayWithSchedule(IContent content)
+ private ContentItemDisplayWithSchedule? MapToDisplayWithSchedule(IContent? content)
{
- ContentItemDisplayWithSchedule display = _umbracoMapper.Map(content, context =>
+ if (content is null)
{
- context.Items["CurrentUser"] = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
+ return null;
+ }
+
+ ContentItemDisplayWithSchedule? display = _umbracoMapper.Map(content, context =>
+ {
+ context.Items["CurrentUser"] = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser;
context.Items["Schedule"] = _contentService.GetContentScheduleByContentId(content.Id);
});
- display.AllowPreview = display.AllowPreview && content.Trashed == false && content.ContentType.IsElement == false;
+
+ if (display is not null)
+ {
+ display.AllowPreview = display.AllowPreview && content?.Trashed == false && content.ContentType.IsElement == false;
+ }
+
return display;
}
@@ -2642,8 +2717,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var content = MapToDisplay(version);
return culture == null
- ? content.Variants?.FirstOrDefault() //No culture set - so this is an invariant node - so just list me the first item in here
- : content.Variants?.FirstOrDefault(x => x.Language?.IsoCode == culture);
+ ? content?.Variants?.FirstOrDefault() //No culture set - so this is an invariant node - so just list me the first item in here
+ : content?.Variants?.FirstOrDefault(x => x.Language?.IsoCode == culture);
}
[Authorize(Policy = AuthorizationPolicies.ContentPermissionRollbackById)]
diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs
index 38f3c82008..3c867ac88e 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeControllerBase.cs
@@ -76,7 +76,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// Whether the composite content types should be applicable for an element type
///
- protected ActionResult>> PerformGetAvailableCompositeContentTypes(
+ protected ActionResult>> PerformGetAvailableCompositeContentTypes(
int contentTypeId,
UmbracoObjectTypes type,
string[]? filterContentTypes,
@@ -146,33 +146,39 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return availableCompositions.Results
.Select(x =>
- new Tuple(UmbracoMapper.Map(x.Composition),
+ new Tuple(UmbracoMapper.Map(x.Composition),
x.Allowed))
.Select(x =>
{
//we need to ensure that the item is enabled if it is already selected
// but do not allow it if it is any of the ancestors
- if (compAliases.Contains(x.Item1.Alias) && ancestors.Contains(x.Item1.Alias) == false)
+ if (compAliases.Contains(x.Item1?.Alias) && ancestors.Contains(x.Item1?.Alias) == false)
{
//re-set x to be allowed (NOTE: I didn't know you could set an enumerable item in a lambda!)
- x = new Tuple(x.Item1, true);
+ x = new Tuple(x.Item1, true);
}
//translate the name
- x.Item1.Name = TranslateItem(x.Item1.Name);
+ if (x.Item1 is not null)
+ {
+ x.Item1.Name = TranslateItem(x.Item1.Name);
+ }
- IContentTypeComposition contentType = allContentTypes.FirstOrDefault(c => c.Key == x.Item1.Key);
- EntityContainer[] containers = GetEntityContainers(contentType, type)?.ToArray();
+ IContentTypeComposition? contentType = allContentTypes.FirstOrDefault(c => c.Key == x.Item1?.Key);
+ EntityContainer[]? containers = GetEntityContainers(contentType, type)?.ToArray();
var containerPath =
$"/{(containers != null && containers.Any() ? $"{string.Join("/", containers.Select(c => c.Name))}/" : null)}";
- x.Item1.AdditionalData["containerPath"] = containerPath;
+ if (x.Item1 is not null)
+ {
+ x.Item1.AdditionalData["containerPath"] = containerPath;
+ }
return x;
})
.ToList();
}
- private IEnumerable GetEntityContainers(IContentTypeComposition contentType,
+ private IEnumerable? GetEntityContainers(IContentTypeComposition? contentType,
UmbracoObjectTypes type)
{
if (contentType == null)
@@ -206,7 +212,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (contentTypeId > 0)
{
- IContentTypeComposition source;
+ IContentTypeComposition? source;
switch (type)
{
@@ -262,6 +268,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return composedOf
.Select(UmbracoMapper.Map)
+ .WhereNotNull()
.Select(TranslateName)
.ToList();
}
@@ -279,20 +286,20 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
text = text.Substring(1);
- return CultureDictionary[text].IfNullOrWhiteSpace(text);
+ return CultureDictionary[text]?.IfNullOrWhiteSpace(text);
}
- protected ActionResult PerformPostSave(
+ protected ActionResult PerformPostSave(
TContentTypeSave contentTypeSave,
Func getContentType,
- Action saveContentType,
+ Action saveContentType,
Action? beforeCreateNew = null)
where TContentTypeDisplay : ContentTypeCompositionDisplay
where TContentTypeSave : ContentTypeSave
where TPropertyType : PropertyTypeBasic
{
var ctId = Convert.ToInt32(contentTypeSave.Id);
- TContentType ct = ctId > 0 ? getContentType(ctId) : null;
+ TContentType? ct = ctId > 0 ? getContentType(ctId) : null;
if (ctId > 0 && ct == null)
{
return NotFound();
@@ -304,7 +311,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// works since that is based on aliases.
IEnumerable allAliases = ContentTypeService.GetAllContentTypeAliases();
var exists = allAliases.InvariantContains(contentTypeSave.Alias);
- if (exists && (ctId == 0 || !ct.Alias.InvariantEquals(contentTypeSave.Alias)))
+ if (exists && (ctId == 0 || (!ct?.Alias.InvariantEquals(contentTypeSave.Alias) ?? false)))
{
ModelState.AddModelError("Alias",
LocalizedTextService.Localize("editcontenttype", "aliasAlreadyExists"));
@@ -315,7 +322,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (ModelState.IsValid == false)
{
- TContentTypeDisplay err =
+ TContentTypeDisplay? err =
CreateModelStateValidationEror(ctId, contentTypeSave, ct);
return ValidationProblem(err);
}
@@ -338,7 +345,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
catch (Exception ex)
{
- TContentTypeDisplay responseEx =
+ TContentTypeDisplay? responseEx =
CreateInvalidCompositionResponseException(
ex, contentTypeSave, ct, ctId);
if (responseEx != null)
@@ -347,7 +354,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- TContentTypeDisplay exResult =
+ TContentTypeDisplay? exResult =
CreateCompositionValidationExceptionIfInvalid(
contentTypeSave, ct);
if (exResult != null)
@@ -381,7 +388,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//save as new
- TContentType newCt = null;
+ TContentType? newCt = null;
try
{
//This mapping will cause a lot of content type validation to occur which we need to deal with
@@ -389,7 +396,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
catch (Exception ex)
{
- TContentTypeDisplay responseEx =
+ TContentTypeDisplay? responseEx =
CreateInvalidCompositionResponseException(
ex, contentTypeSave, ct, ctId);
if (responseEx is null)
@@ -400,7 +407,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return ValidationProblem(responseEx);
}
- TContentTypeDisplay exResult =
+ TContentTypeDisplay? exResult =
CreateCompositionValidationExceptionIfInvalid(
contentTypeSave, newCt);
if (exResult != null)
@@ -419,7 +426,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (allowItselfAsChild && newCt != null)
{
newCt.AllowedContentTypes =
- newCt.AllowedContentTypes.Union(
+ newCt.AllowedContentTypes?.Union(
new[] { new ContentTypeSort(newCt.Id, allowIfselfAsChildSortOrder) }
);
saveContentType(newCt);
@@ -441,7 +448,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
foreach (ValidationResult r in validationResults)
foreach (var m in r.MemberNames)
{
- modelState.AddModelError(m, r.ErrorMessage);
+ modelState.AddModelError(m, r.ErrorMessage ?? string.Empty);
}
}
@@ -469,7 +476,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return Content(toMove.Path, MediaTypeNames.Text.Plain, Encoding.UTF8);
}
- switch (result.Result.Result)
+ switch (result.Result?.Result)
{
case MoveOperationStatusType.FailedParentNotFound:
return NotFound();
@@ -494,19 +501,19 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
Func getContentType,
Func?>> doCopy)
{
- TContentType toMove = getContentType(move.Id);
+ TContentType? toMove = getContentType(move.Id);
if (toMove == null)
{
return NotFound();
}
- Attempt> result = doCopy(toMove, move.ParentId);
+ Attempt?> result = doCopy(toMove, move.ParentId);
if (result.Success)
{
return Content(toMove.Path, MediaTypeNames.Text.Plain, Encoding.UTF8);
}
- switch (result.Result.Result)
+ switch (result.Result?.Result)
{
case MoveOperationStatusType.FailedParentNotFound:
return NotFound();
@@ -526,19 +533,19 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- private TContentTypeDisplay CreateCompositionValidationExceptionIfInvalid(TContentTypeSave contentTypeSave, TContentType composition)
+ private TContentTypeDisplay? CreateCompositionValidationExceptionIfInvalid(TContentTypeSave contentTypeSave, TContentType? composition)
where TContentTypeSave : ContentTypeSave
where TPropertyType : PropertyTypeBasic
where TContentTypeDisplay : ContentTypeCompositionDisplay
{
- IContentTypeBaseService service = GetContentTypeService();
- Attempt validateAttempt = service.ValidateComposition(composition);
+ IContentTypeBaseService? service = GetContentTypeService();
+ Attempt validateAttempt = service?.ValidateComposition(composition) ?? Attempt.Fail();
if (validateAttempt == false)
{
// if it's not successful then we need to return some model state for the property type and property group
// aliases that are duplicated
- IEnumerable duplicatePropertyTypeAliases = validateAttempt.Result.Distinct();
+ IEnumerable? duplicatePropertyTypeAliases = validateAttempt.Result?.Distinct();
var invalidPropertyGroupAliases =
(validateAttempt.Exception as InvalidCompositionException)?.PropertyGroupAliases ??
Array.Empty();
@@ -546,17 +553,21 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
AddCompositionValidationErrors(contentTypeSave,
duplicatePropertyTypeAliases, invalidPropertyGroupAliases);
- TContentTypeDisplay display = UmbracoMapper.Map(composition);
+ TContentTypeDisplay? display = UmbracoMapper.Map(composition);
//map the 'save' data on top
display = UmbracoMapper.Map(contentTypeSave, display);
- display.Errors = ModelState.ToErrorDictionary();
+ if (display is not null)
+ {
+ display.Errors = ModelState.ToErrorDictionary();
+ }
+
return display;
}
return null;
}
- public IContentTypeBaseService GetContentTypeService()
+ public IContentTypeBaseService? GetContentTypeService()
where T : IContentTypeComposition
{
if (typeof(T).Implements())
@@ -585,32 +596,38 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
private void AddCompositionValidationErrors(TContentTypeSave contentTypeSave,
- IEnumerable duplicatePropertyTypeAliases, IEnumerable invalidPropertyGroupAliases)
+ IEnumerable? duplicatePropertyTypeAliases, IEnumerable? invalidPropertyGroupAliases)
where TContentTypeSave : ContentTypeSave
where TPropertyType : PropertyTypeBasic
{
- foreach (var propertyTypeAlias in duplicatePropertyTypeAliases)
+ if (duplicatePropertyTypeAliases is not null)
{
- // Find the property type relating to these
- TPropertyType property = contentTypeSave.Groups.SelectMany(x => x.Properties)
- .Single(x => x.Alias == propertyTypeAlias);
- PropertyGroupBasic group =
- contentTypeSave.Groups.Single(x => x.Properties.Contains(property));
- var propertyIndex = group.Properties.IndexOf(property);
- var groupIndex = contentTypeSave.Groups.IndexOf(group);
+ foreach (var propertyTypeAlias in duplicatePropertyTypeAliases)
+ {
+ // Find the property type relating to these
+ TPropertyType property = contentTypeSave.Groups.SelectMany(x => x.Properties)
+ .Single(x => x.Alias == propertyTypeAlias);
+ PropertyGroupBasic group =
+ contentTypeSave.Groups.Single(x => x.Properties.Contains(property));
+ var propertyIndex = group.Properties.IndexOf(property);
+ var groupIndex = contentTypeSave.Groups.IndexOf(group);
- var key = $"Groups[{groupIndex}].Properties[{propertyIndex}].Alias";
- ModelState.AddModelError(key, "Duplicate property aliases aren't allowed between compositions");
+ var key = $"Groups[{groupIndex}].Properties[{propertyIndex}].Alias";
+ ModelState.AddModelError(key, "Duplicate property aliases aren't allowed between compositions");
+ }
}
- foreach (var propertyGroupAlias in invalidPropertyGroupAliases)
+ if (invalidPropertyGroupAliases is not null)
{
- // Find the property group relating to these
- PropertyGroupBasic group =
- contentTypeSave.Groups.Single(x => x.Alias == propertyGroupAlias);
- var groupIndex = contentTypeSave.Groups.IndexOf(group);
- var key = $"Groups[{groupIndex}].Name";
- ModelState.AddModelError(key, "Different group types aren't allowed between compositions");
+ foreach (var propertyGroupAlias in invalidPropertyGroupAliases)
+ {
+ // Find the property group relating to these
+ PropertyGroupBasic group =
+ contentTypeSave.Groups.Single(x => x.Alias == propertyGroupAlias);
+ var groupIndex = contentTypeSave.Groups.IndexOf(group);
+ var key = $"Groups[{groupIndex}].Name";
+ ModelState.AddModelError(key, "Different group types aren't allowed between compositions");
+ }
}
}
@@ -625,14 +642,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- private TContentTypeDisplay CreateInvalidCompositionResponseException(
- Exception ex, TContentTypeSave contentTypeSave, TContentType ct, int ctId)
+ Exception ex, TContentTypeSave contentTypeSave, TContentType? ct, int ctId)
where TContentTypeDisplay : ContentTypeCompositionDisplay
where TContentTypeSave : ContentTypeSave
where TPropertyType : PropertyTypeBasic
{
- InvalidCompositionException invalidCompositionException = null;
+ InvalidCompositionException? invalidCompositionException = null;
if (ex is InvalidCompositionException)
{
invalidCompositionException = (InvalidCompositionException)ex;
@@ -660,12 +677,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- private TContentTypeDisplay CreateModelStateValidationEror(int ctId,
- TContentTypeSave contentTypeSave, TContentType ct)
+ private TContentTypeDisplay? CreateModelStateValidationEror(int ctId,
+ TContentTypeSave contentTypeSave, TContentType? ct)
where TContentTypeDisplay : ContentTypeCompositionDisplay
where TContentTypeSave : ContentTypeSave
{
- TContentTypeDisplay forDisplay;
+ TContentTypeDisplay? forDisplay;
if (ctId > 0)
{
//Required data is invalid so we cannot continue
@@ -679,7 +696,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
forDisplay = UmbracoMapper.Map(contentTypeSave);
}
- forDisplay.Errors = ModelState.ToErrorDictionary();
+ if (forDisplay is not null)
+ {
+ forDisplay.Errors = ModelState.ToErrorDictionary();
+ }
+
return forDisplay;
}
}
diff --git a/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs b/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs
index a01b88501f..a31ee6b27e 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs
@@ -160,7 +160,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// If set used to look up whether user and group start node permissions will be ignored.
///
[HttpGet]
- public IEnumerable Search(string query, UmbracoEntityTypes type, string searchFrom = null,
+ public IEnumerable Search(string query, UmbracoEntityTypes type, string? searchFrom = null,
Guid? dataTypeKey = null)
{
// NOTE: Theoretically you shouldn't be able to see member data if you don't have access to members right? ... but there is a member picker, so can't really do that
@@ -202,27 +202,31 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return result;
}
- var allowedSections = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.AllowedSections.ToArray();
+ var allowedSections = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.AllowedSections.ToArray();
foreach (KeyValuePair searchableTree in _searchableTreeCollection
.SearchableApplicationTrees.OrderBy(t => t.Value.SortOrder))
{
- if (allowedSections.Contains(searchableTree.Value.AppAlias))
+ if (allowedSections?.Contains(searchableTree.Value.AppAlias) ?? false)
{
- Tree tree = _treeService.GetByAlias(searchableTree.Key);
+ Tree? tree = _treeService.GetByAlias(searchableTree.Key);
if (tree == null)
{
continue; //shouldn't occur
}
- result[Tree.GetRootNodeDisplayName(tree, _localizedTextService)] = new TreeSearchResult
+ var rootNodeDisplayName = Tree.GetRootNodeDisplayName(tree, _localizedTextService);
+ if (rootNodeDisplayName is not null)
{
- Results = searchableTree.Value.SearchableTree.Search(query, 200, 0, out var total),
- TreeAlias = searchableTree.Key,
- AppAlias = searchableTree.Value.AppAlias,
- JsFormatterService = searchableTree.Value.FormatterService,
- JsFormatterMethod = searchableTree.Value.FormatterMethod
- };
+ result[rootNodeDisplayName] = new TreeSearchResult
+ {
+ Results = searchableTree.Value.SearchableTree.Search(query, 200, 0, out var total).WhereNotNull(),
+ TreeAlias = searchableTree.Key,
+ AppAlias = searchableTree.Value.AppAlias,
+ JsFormatterService = searchableTree.Value.FormatterService,
+ JsFormatterMethod = searchableTree.Value.FormatterMethod
+ };
+ }
}
}
@@ -237,8 +241,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
public IConvertToActionResult GetPath(int id, UmbracoEntityTypes type)
{
- ActionResult foundContentResult = GetResultForId(id, type);
- EntityBasic foundContent = foundContentResult.Value;
+ ActionResult foundContentResult = GetResultForId(id, type);
+ EntityBasic? foundContent = foundContentResult.Value;
if (foundContent is null)
{
return foundContentResult;
@@ -257,8 +261,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
public IConvertToActionResult GetPath(Guid id, UmbracoEntityTypes type)
{
- ActionResult foundContentResult = GetResultForKey(id, type);
- EntityBasic foundContent = foundContentResult.Value;
+ ActionResult foundContentResult = GetResultForKey(id, type);
+ EntityBasic? foundContent = foundContentResult.Value;
if (foundContent is null)
{
return foundContentResult;
@@ -333,14 +337,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[HttpGet]
[HttpPost]
- public IDictionary GetUrlsByIds([FromJsonPath] int[] ids, [FromQuery] UmbracoEntityTypes type, [FromQuery] string culture = null)
+ public IDictionary GetUrlsByIds([FromJsonPath] int[] ids, [FromQuery] UmbracoEntityTypes type, [FromQuery] string? culture = null)
{
if (ids == null || !ids.Any())
{
- return new Dictionary();
+ return new Dictionary();
}
- string MediaOrDocumentUrl(int id)
+ string? MediaOrDocumentUrl(int id)
{
switch (type)
{
@@ -349,7 +353,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case UmbracoEntityTypes.Media:
{
- IPublishedContent media = _publishedContentQuery.Media(id);
+ IPublishedContent? media = _publishedContentQuery.Media(id);
// NOTE: If culture is passed here we get an empty string rather than a media item URL.
return _publishedUrlProvider.GetMediaUrl(media, culture: null);
@@ -382,14 +386,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[HttpGet]
[HttpPost]
- public IDictionary GetUrlsByIds([FromJsonPath] Guid[] ids, [FromQuery] UmbracoEntityTypes type, [FromQuery] string culture = null)
+ public IDictionary GetUrlsByIds([FromJsonPath] Guid[] ids, [FromQuery] UmbracoEntityTypes type, [FromQuery] string? culture = null)
{
if (ids == null || !ids.Any())
{
- return new Dictionary();
+ return new Dictionary();
}
- string MediaOrDocumentUrl(Guid id)
+ string? MediaOrDocumentUrl(Guid id)
{
return type switch
{
@@ -424,15 +428,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[HttpGet]
[HttpPost]
- public IDictionary GetUrlsByIds([FromJsonPath] Udi[] ids, [FromQuery] UmbracoEntityTypes type, [FromQuery] string culture = null)
+ public IDictionary GetUrlsByIds([FromJsonPath] Udi[] ids, [FromQuery] UmbracoEntityTypes type, [FromQuery] string? culture = null)
{
if (ids == null || !ids.Any())
{
- return new Dictionary();
+ return new Dictionary();
}
// TODO: PMJ 2021-09-27 - Should GetUrl(Udi) exist as an extension method on UrlProvider/IUrlProvider (in v9)
- string MediaOrDocumentUrl(Udi id)
+ string? MediaOrDocumentUrl(Udi id)
{
if (id is not GuidUdi guidUdi)
{
@@ -472,11 +476,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[HttpGet]
[HttpPost]
[Obsolete("Use GetUrlsByIds instead.")]
- public IDictionary GetUrlsByUdis([FromJsonPath] Udi[] udis, string? culture = null)
+ public IDictionary GetUrlsByUdis([FromJsonPath] Udi[] udis, string? culture = null)
{
if (udis == null || !udis.Any())
{
- return new Dictionary();
+ return new Dictionary();
}
var udiEntityType = udis.First().EntityType;
@@ -546,7 +550,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public ActionResult GetByQuery(string query, int nodeContextId, UmbracoEntityTypes type)
+ public ActionResult? GetByQuery(string query, int nodeContextId, UmbracoEntityTypes type)
{
// TODO: Rename this!!! It's misleading, it should be GetByXPath
@@ -558,7 +562,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var q = ParseXPathQuery(query, nodeContextId);
- IPublishedContent node = _publishedContentQuery.ContentSingleAtXPath(q);
+ IPublishedContent? node = _publishedContentQuery.ContentSingleAtXPath(q);
if (node == null)
{
@@ -575,8 +579,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
id,
nodeid =>
{
- IEntitySlim ent = _entityService.Get(nodeid);
- return ent.Path.Split(Constants.CharArrays.Comma).Reverse();
+ IEntitySlim? ent = _entityService.Get(nodeid);
+ return ent?.Path.Split(Constants.CharArrays.Comma).Reverse();
},
i => _publishedContentQuery.Content(i) != null);
@@ -593,7 +597,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
[HttpGet]
- public UrlAndAnchors GetUrlAndAnchors(int id, string culture = "*")
+ public UrlAndAnchors GetUrlAndAnchors(int id, string? culture = "*")
{
culture = culture ?? ClientCulture();
@@ -606,6 +610,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[HttpPost]
public IEnumerable GetAnchors(AnchorsModel model)
{
+ if (model.RteContent is null)
+ {
+ return Enumerable.Empty();
+ }
+
IEnumerable anchorValues = _contentService.GetAnchorValuesFromRTEContent(model.RteContent);
return anchorValues;
}
@@ -631,15 +640,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return Enumerable.Empty();
}
- var pr = new List(nodes.Select(_umbracoMapper.Map));
+ var pr = new List(nodes.Select(_umbracoMapper.Map).WhereNotNull());
return pr;
}
// else proceed as usual
return _entityService.GetChildren(id, objectType.Value)
- .WhereNotNull()
- .Select(_umbracoMapper.Map);
+ .Select(_umbracoMapper.Map)
+ .WhereNotNull();
}
//now we need to convert the unknown ones
@@ -768,7 +777,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
out totalRecords,
filter.IsNullOrWhiteSpace()
? null
- : _sqlContext.Query().Where(x => x.Name.Contains(filter)),
+ : _sqlContext.Query().Where(x => x.Name!.Contains(filter)),
Ordering.By(orderBy, orderDirection));
@@ -782,15 +791,19 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
Items = entities.Select(source =>
{
- EntityBasic target = _umbracoMapper.Map(source, context =>
+ EntityBasic? target = _umbracoMapper.Map(source, context =>
{
context.SetCulture(culture);
context.SetCulture(culture);
});
- //TODO: Why is this here and not in the mapping?
- target.AdditionalData["hasChildren"] = source.HasChildren;
+
+ if (target is not null)
+ {
+ //TODO: Why is this here and not in the mapping?
+ target.AdditionalData["hasChildren"] = source.HasChildren;
+ }
return target;
- })
+ }).WhereNotNull(),
};
return pagedResult;
@@ -815,11 +828,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
switch (type)
{
case UmbracoEntityTypes.Document:
- return _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.CalculateContentStartNodeIds(
- _entityService, _appCaches);
+ return _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.CalculateContentStartNodeIds(
+ _entityService, _appCaches) ?? Array.Empty();
case UmbracoEntityTypes.Media:
- return _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.CalculateMediaStartNodeIds(
- _entityService, _appCaches);
+ return _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.CalculateMediaStartNodeIds(
+ _entityService, _appCaches) ?? Array.Empty();
default:
return Array.Empty();
}
@@ -864,18 +877,18 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
entities = aids == null || aids.Contains(Constants.System.Root) || ignoreUserStartNodes
? _entityService.GetPagedDescendants(objectType.Value, pageNumber - 1, pageSize,
out totalRecords,
- _sqlContext.Query().Where(x => x.Name.Contains(filter)),
+ _sqlContext.Query().Where(x => x.Name!.Contains(filter)),
Ordering.By(orderBy, orderDirection), false)
: _entityService.GetPagedDescendants(aids, objectType.Value, pageNumber - 1, pageSize,
out totalRecords,
- _sqlContext.Query().Where(x => x.Name.Contains(filter)),
+ _sqlContext.Query().Where(x => x.Name!.Contains(filter)),
Ordering.By(orderBy, orderDirection));
}
else
{
entities = _entityService.GetPagedDescendants(id, objectType.Value, pageNumber - 1, pageSize,
out totalRecords,
- _sqlContext.Query().Where(x => x.Name.Contains(filter)),
+ _sqlContext.Query().Where(x => x.Name!.Contains(filter)),
Ordering.By(orderBy, orderDirection));
}
@@ -886,7 +899,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var pagedResult = new PagedResult(totalRecords, pageNumber, pageSize)
{
- Items = entities.Select(MapEntities())
+ Items = entities.Select(MapEntities()).WhereNotNull(),
};
return pagedResult;
@@ -920,7 +933,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[ModelBinder(typeof(HttpQueryStringModelBinder))]
FormCollection queryStrings)
{
- IEntitySlim entity = _entityService.Get(id);
+ IEntitySlim? entity = _entityService.Get(id);
if (entity is null)
{
return NotFound();
@@ -938,7 +951,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// If set to true, user and group start node permissions will be ignored.
///
private IEnumerable ExamineSearch(string query, UmbracoEntityTypes entityType,
- string searchFrom = null, bool ignoreUserStartNodes = false)
+ string? searchFrom = null, bool ignoreUserStartNodes = false)
{
var culture = ClientCulture();
return _treeSearcher.ExamineSearch(query, entityType, 200, 0, out _, culture, searchFrom,
@@ -953,8 +966,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// TODO: Need to check for Object types that support hierarchic here, some might not.
return _entityService.GetChildren(id, objectType.Value)
- .WhereNotNull()
- .Select(MapEntities());
+ .Select(MapEntities())
+ .WhereNotNull();
}
//now we need to convert the unknown ones
@@ -970,30 +983,30 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
private IEnumerable GetResultForAncestors(int id, UmbracoEntityTypes entityType,
- FormCollection queryStrings = null)
+ FormCollection? queryStrings = null)
{
UmbracoObjectTypes? objectType = ConvertToObjectType(entityType);
if (objectType.HasValue)
{
// TODO: Need to check for Object types that support hierarchic here, some might not.
- var ids = _entityService.Get(id).Path.Split(Constants.CharArrays.Comma)
+ var ids = _entityService.Get(id)?.Path.Split(Constants.CharArrays.Comma)
.Select(s => int.Parse(s, CultureInfo.InvariantCulture)).Distinct().ToArray();
var ignoreUserStartNodes =
IsDataTypeIgnoringUserStartNodes(queryStrings?.GetValue("dataTypeId"));
if (ignoreUserStartNodes == false)
{
- int[] aids = null;
+ int[]? aids = null;
switch (entityType)
{
case UmbracoEntityTypes.Document:
- aids = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser
+ aids = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?
.CalculateContentStartNodeIds(_entityService, _appCaches);
break;
case UmbracoEntityTypes.Media:
aids =
- _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.CalculateMediaStartNodeIds(
+ _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.CalculateMediaStartNodeIds(
_entityService, _appCaches);
break;
}
@@ -1002,18 +1015,21 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
var lids = new List();
var ok = false;
- foreach (var i in ids)
+ if (ids is not null)
{
- if (ok)
+ foreach (var i in ids)
{
- lids.Add(i);
- continue;
- }
+ if (ok)
+ {
+ lids.Add(i);
+ continue;
+ }
- if (aids.Contains(i))
- {
- lids.Add(i);
- ok = true;
+ if (aids.Contains(i))
+ {
+ lids.Add(i);
+ ok = true;
+ }
}
}
@@ -1023,12 +1039,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var culture = queryStrings?.GetValue("culture");
- return ids.Length == 0
+ return ids is null || ids.Length == 0
? Enumerable.Empty()
: _entityService.GetAll(objectType.Value, ids)
- .WhereNotNull()
.OrderBy(x => x.Level)
- .Select(MapEntities(culture));
+ .Select(MapEntities(culture))
+ .WhereNotNull();
}
//now we need to convert the unknown ones
@@ -1056,13 +1072,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (objectType.HasValue)
{
IEnumerable entities = _entityService.GetAll(objectType.Value, keys)
- .WhereNotNull()
- .Select(MapEntities());
+ .Select(MapEntities())
+ .WhereNotNull();
// entities are in "some" order, put them back in order
var xref = entities.ToDictionary(x => x.Key);
IEnumerable result = keys.Select(x => xref.ContainsKey(x) ? xref[x] : null)
- .Where(x => x != null);
+ .WhereNotNull();
return result;
}
@@ -1092,13 +1108,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (objectType.HasValue)
{
IEnumerable entities = _entityService.GetAll(objectType.Value, ids)
- .WhereNotNull()
- .Select(MapEntities());
+ .Select(MapEntities())
+ .WhereNotNull();
// entities are in "some" order, put them back in order
- var xref = entities.ToDictionary(x => x.Id);
+ var xref = entities.Where(x => x.Id != null).ToDictionary(x => x.Id!);
IEnumerable result = ids.Select(x => xref.ContainsKey(x) ? xref[x] : null)
- .Where(x => x != null);
+ .WhereNotNull();
return result;
}
@@ -1117,12 +1133,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- private ActionResult GetResultForKey(Guid key, UmbracoEntityTypes entityType)
+ private ActionResult GetResultForKey(Guid key, UmbracoEntityTypes entityType)
{
UmbracoObjectTypes? objectType = ConvertToObjectType(entityType);
if (objectType.HasValue)
{
- IEntitySlim found = _entityService.Get(key, objectType.Value);
+ IEntitySlim? found = _entityService.Get(key, objectType.Value);
if (found == null)
{
return NotFound();
@@ -1145,7 +1161,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case UmbracoEntityTypes.Macro:
case UmbracoEntityTypes.Template:
- ITemplate template = _fileService.GetTemplate(key);
+ ITemplate? template = _fileService.GetTemplate(key);
if (template is null)
{
return NotFound();
@@ -1159,12 +1175,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- private ActionResult GetResultForId(int id, UmbracoEntityTypes entityType)
+ private ActionResult GetResultForId(int id, UmbracoEntityTypes entityType)
{
UmbracoObjectTypes? objectType = ConvertToObjectType(entityType);
if (objectType.HasValue)
{
- IEntitySlim found = _entityService.Get(id, objectType.Value);
+ IEntitySlim? found = _entityService.Get(id, objectType.Value);
if (found == null)
{
return NotFound();
@@ -1187,7 +1203,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
case UmbracoEntityTypes.Macro:
case UmbracoEntityTypes.Template:
- ITemplate template = _fileService.GetTemplate(id);
+ ITemplate? template = _fileService.GetTemplate(id);
if (template is null)
{
return NotFound();
@@ -1235,7 +1251,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// ignored.
///
///
- public IEnumerable GetAll(UmbracoEntityTypes type, string postFilter) =>
+ public IEnumerable? GetAll(UmbracoEntityTypes type, string postFilter) =>
GetResultForAll(type, postFilter);
///
@@ -1244,14 +1260,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// A string where filter that will filter the results dynamically with linq - optional
///
- private IEnumerable GetResultForAll(UmbracoEntityTypes entityType, string postFilter = null)
+ private IEnumerable? GetResultForAll(UmbracoEntityTypes entityType, string? postFilter = null)
{
UmbracoObjectTypes? objectType = ConvertToObjectType(entityType);
if (objectType.HasValue)
{
// TODO: Should we order this by something ?
IEnumerable entities =
- _entityService.GetAll(objectType.Value).WhereNotNull().Select(MapEntities());
+ _entityService.GetAll(objectType.Value).Select(MapEntities()).WhereNotNull();
return ExecutePostFilter(entities, postFilter);
}
@@ -1259,15 +1275,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
switch (entityType)
{
case UmbracoEntityTypes.Template:
- IEnumerable templates = _fileService.GetTemplates();
- IEnumerable filteredTemplates = ExecutePostFilter(templates, postFilter);
- return filteredTemplates.Select(MapEntities());
+ IEnumerable? templates = _fileService.GetTemplates();
+ IEnumerable? filteredTemplates = ExecutePostFilter(templates, postFilter);
+ return filteredTemplates?.Select(MapEntities()).WhereNotNull();
case UmbracoEntityTypes.Macro:
//Get all macros from the macro service
IOrderedEnumerable macros = _macroService.GetAll().WhereNotNull().OrderBy(x => x.Name);
- IEnumerable filteredMacros = ExecutePostFilter(macros, postFilter);
- return filteredMacros.Select(MapEntities());
+ IEnumerable? filteredMacros = ExecutePostFilter(macros, postFilter);
+ return filteredMacros?.Select(MapEntities()).WhereNotNull();
case UmbracoEntityTypes.PropertyType:
@@ -1278,8 +1294,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
.ToArray()
.SelectMany(x => x.PropertyTypes)
.DistinctBy(composition => composition.Alias);
- IEnumerable filteredPropertyTypes = ExecutePostFilter(propertyTypes, postFilter);
- return _umbracoMapper.MapEnumerable(filteredPropertyTypes);
+ IEnumerable? filteredPropertyTypes = ExecutePostFilter(propertyTypes, postFilter);
+ return _umbracoMapper.MapEnumerable(filteredPropertyTypes ?? Enumerable.Empty()).WhereNotNull();
case UmbracoEntityTypes.PropertyGroup:
@@ -1290,14 +1306,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
.ToArray()
.SelectMany(x => x.PropertyGroups)
.DistinctBy(composition => composition.Name);
- IEnumerable filteredpropertyGroups = ExecutePostFilter(propertyGroups, postFilter);
- return _umbracoMapper.MapEnumerable(filteredpropertyGroups);
+ IEnumerable? filteredpropertyGroups = ExecutePostFilter(propertyGroups, postFilter);
+ return _umbracoMapper.MapEnumerable(filteredpropertyGroups ?? Enumerable.Empty()).WhereNotNull();
case UmbracoEntityTypes.User:
IEnumerable users = _userService.GetAll(0, int.MaxValue, out _);
- IEnumerable filteredUsers = ExecutePostFilter(users, postFilter);
- return _umbracoMapper.MapEnumerable(filteredUsers);
+ IEnumerable? filteredUsers = ExecutePostFilter(users, postFilter);
+ return _umbracoMapper.MapEnumerable(filteredUsers ?? Enumerable.Empty()).WhereNotNull();
case UmbracoEntityTypes.Stylesheet:
@@ -1306,7 +1322,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
throw new NotSupportedException("Filtering on stylesheets is not currently supported");
}
- return _fileService.GetStylesheets().Select(MapEntities());
+ return _fileService.GetStylesheets().Select(MapEntities()).WhereNotNull();
case UmbracoEntityTypes.Script:
@@ -1315,7 +1331,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
throw new NotSupportedException("Filtering on scripts is not currently supported");
}
- return _fileService.GetScripts().Select(MapEntities());
+ return _fileService.GetScripts().Select(MapEntities()).WhereNotNull();
case UmbracoEntityTypes.PartialView:
@@ -1324,7 +1340,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
throw new NotSupportedException("Filtering on partial views is not currently supported");
}
- return _fileService.GetPartialViews().Select(MapEntities());
+ return _fileService.GetPartialViews().Select(MapEntities()).WhereNotNull();
case UmbracoEntityTypes.Language:
@@ -1333,7 +1349,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
throw new NotSupportedException("Filtering on languages is not currently supported");
}
- return _localizationService.GetAllLanguages().Select(MapEntities());
+ return _localizationService.GetAllLanguages().Select(MapEntities()).WhereNotNull();
case UmbracoEntityTypes.DictionaryItem:
if (!postFilter.IsNullOrWhiteSpace())
@@ -1349,31 +1365,31 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- private IEnumerable ExecutePostFilter(IEnumerable entities, string postFilter)
+ private IEnumerable? ExecutePostFilter(IEnumerable? entities, string? postFilter)
{
if (postFilter.IsNullOrWhiteSpace())
{
return entities;
}
- var postFilterConditions = postFilter.Split(Constants.CharArrays.Ampersand);
+ var postFilterConditions = postFilter!.Split(Constants.CharArrays.Ampersand);
foreach (var postFilterCondition in postFilterConditions)
{
- QueryCondition queryCondition = BuildQueryCondition(postFilterCondition);
+ QueryCondition? queryCondition = BuildQueryCondition(postFilterCondition);
if (queryCondition != null)
{
Expression> whereClauseExpression = queryCondition.BuildCondition("x");
- entities = entities.Where(whereClauseExpression.Compile());
+ entities = entities?.Where(whereClauseExpression.Compile());
}
}
return entities;
}
- private static QueryCondition BuildQueryCondition(string postFilter)
+ private static QueryCondition? BuildQueryCondition(string postFilter)
{
var postFilterParts = postFilter.Split(_postFilterSplitStrings, 2, StringSplitOptions.RemoveEmptyEntries);
@@ -1399,7 +1415,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
Type type = typeof(T);
- PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
+ PropertyInfo? property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property == null)
{
@@ -1419,19 +1435,19 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return queryCondition;
}
- private Func