From 521023372b9ecda89522f44974cea45adf2ce6aa Mon Sep 17 00:00:00 2001
From: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Date: Tue, 11 Jan 2022 11:47:31 +0100
Subject: [PATCH] Fix extension methods
---
src/Umbraco.Core/Attempt.cs | 4 +-
src/Umbraco.Core/AttemptOfTResult.cs | 18 +--
.../Extensions/AssemblyExtensions.cs | 22 +--
.../Extensions/ClaimsIdentityExtensions.cs | 46 ++++---
.../Extensions/ContentVariationExtensions.cs | 6 +-
.../Extensions/DelegateExtensions.cs | 12 +-
.../Extensions/DictionaryExtensions.cs | 22 +--
.../Extensions/EnumerableExtensions.cs | 9 +-
.../NameValueCollectionExtensions.cs | 10 +-
.../Extensions/ObjectExtensions.cs | 127 +++++++++---------
.../Extensions/PublishedContentExtensions.cs | 42 +++---
.../Extensions/PublishedPropertyExtension.cs | 4 +-
.../Extensions/StringExtensions.cs | 33 +++--
src/Umbraco.Core/Extensions/TypeExtensions.cs | 38 +++---
src/Umbraco.Core/Extensions/UriExtensions.cs | 2 +-
.../Extensions/WaitHandleExtensions.cs | 6 +-
src/Umbraco.Core/Extensions/XmlExtensions.cs | 58 ++++----
src/Umbraco.Core/Xml/XmlNodeListFactory.cs | 16 +--
18 files changed, 255 insertions(+), 220 deletions(-)
diff --git a/src/Umbraco.Core/Attempt.cs b/src/Umbraco.Core/Attempt.cs
index eddd2c8785..0a8987726a 100644
--- a/src/Umbraco.Core/Attempt.cs
+++ b/src/Umbraco.Core/Attempt.cs
@@ -17,9 +17,9 @@ namespace Umbraco.Cms.Core
/// The type of the attempted operation result.
/// The result of the attempt.
/// The successful attempt.
- public static Attempt Succeed(TResult result)
+ public static Attempt Succeed(TResult? result)
{
- return Attempt.Succeed(result);
+ return Attempt.Succeed(result);
}
///
diff --git a/src/Umbraco.Core/AttemptOfTResult.cs b/src/Umbraco.Core/AttemptOfTResult.cs
index cebabe214b..ebe7d57d7f 100644
--- a/src/Umbraco.Core/AttemptOfTResult.cs
+++ b/src/Umbraco.Core/AttemptOfTResult.cs
@@ -10,7 +10,7 @@ namespace Umbraco.Cms.Core
public struct Attempt
{
// private - use Succeed() or Fail() methods to create attempts
- private Attempt(bool success, TResult result, Exception exception)
+ private Attempt(bool? success, TResult? result, Exception? exception)
{
Success = success;
Result = result;
@@ -20,22 +20,22 @@ namespace Umbraco.Cms.Core
///
/// Gets a value indicating whether this was successful.
///
- public bool Success { get; }
+ public bool? Success { get; }
///
/// Gets the exception associated with an unsuccessful attempt.
///
- public Exception Exception { get; }
+ public Exception? Exception { get; }
///
/// Gets the attempt result.
///
- public TResult Result { get; }
+ public TResult? Result { get; }
///
/// Gets the attempt result, if successful, else a default value.
///
- public TResult ResultOr(TResult value) => Success ? Result : value;
+ public TResult? ResultOr(TResult? value) => Success.HasValue && Success.Value ? Result : value;
// optimize, use a singleton failed attempt
private static readonly Attempt Failed = new Attempt(false, default(TResult), null);
@@ -54,7 +54,7 @@ namespace Umbraco.Cms.Core
///
/// The result of the attempt.
/// The successful attempt.
- public static Attempt Succeed(TResult result)
+ public static Attempt Succeed(TResult? result)
{
return new Attempt(true, result, null);
}
@@ -73,7 +73,7 @@ namespace Umbraco.Cms.Core
///
/// The exception causing the failure of the attempt.
/// The failed attempt.
- public static Attempt Fail(Exception exception)
+ public static Attempt Fail(Exception? exception)
{
return new Attempt(false, default(TResult), exception);
}
@@ -115,7 +115,7 @@ namespace Umbraco.Cms.Core
/// A value indicating whether the attempt is successful.
/// The result of the attempt.
/// The attempt.
- public static Attempt If(bool condition, TResult result)
+ public static Attempt If(bool condition, TResult? result)
{
return new Attempt(condition, result, null);
}
@@ -125,7 +125,7 @@ namespace Umbraco.Cms.Core
///
///
///
- public static implicit operator bool(Attempt a)
+ public static implicit operator bool?(Attempt a)
{
return a.Success;
}
diff --git a/src/Umbraco.Core/Extensions/AssemblyExtensions.cs b/src/Umbraco.Core/Extensions/AssemblyExtensions.cs
index cefaae5b86..aea0f847ab 100644
--- a/src/Umbraco.Core/Extensions/AssemblyExtensions.cs
+++ b/src/Umbraco.Core/Extensions/AssemblyExtensions.cs
@@ -23,8 +23,7 @@ namespace Umbraco.Extensions
{
return _rootDir;
}
-
- var codeBase = executingAssembly.CodeBase;
+ var codeBase = executingAssembly.Location;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
var baseDirectory = Path.GetDirectoryName(path);
@@ -45,7 +44,7 @@ namespace Umbraco.Extensions
///
public static FileInfo GetAssemblyFile(this Assembly assembly)
{
- var codeBase = assembly.CodeBase;
+ var codeBase = assembly.Location;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
return new FileInfo(path);
@@ -58,7 +57,7 @@ namespace Umbraco.Extensions
///
public static bool IsAppCodeAssembly(this Assembly assembly)
{
- if (assembly.FullName.StartsWith("App_Code"))
+ if (assembly.FullName!.StartsWith("App_Code"))
{
try
{
@@ -82,7 +81,7 @@ namespace Umbraco.Extensions
public static bool IsGlobalAsaxAssembly(this Assembly assembly)
{
//only way I can figure out how to test is by the name
- return assembly.FullName.StartsWith("App_global.asax");
+ return assembly.FullName!.StartsWith("App_global.asax");
}
///
@@ -90,12 +89,17 @@ namespace Umbraco.Extensions
///
///
///
- public static FileInfo GetAssemblyFile(this AssemblyName assemblyName)
+ public static FileInfo? GetAssemblyFile(this AssemblyName assemblyName)
{
var codeBase = assemblyName.CodeBase;
- var uri = new Uri(codeBase);
- var path = uri.LocalPath;
- return new FileInfo(path);
+ if (!string.IsNullOrEmpty(codeBase))
+ {
+ var uri = new Uri(codeBase);
+ var path = uri.LocalPath;
+ return new FileInfo(path);
+ }
+
+ return null;
}
}
diff --git a/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs b/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs
index 9b3674b07b..19d2de1c85 100644
--- a/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs
+++ b/src/Umbraco.Core/Extensions/ClaimsIdentityExtensions.cs
@@ -13,7 +13,7 @@ namespace Umbraco.Extensions
{
public static class ClaimsIdentityExtensions
{
- public static T GetUserId(this IIdentity identity)
+ public static T? GetUserId(this IIdentity identity)
{
var strId = identity.GetUserId();
var converted = strId.TryConvertTo();
@@ -27,11 +27,11 @@ namespace Umbraco.Extensions
///
/// The string value of the user id if found otherwise null
///
- public static string GetUserId(this IIdentity identity)
+ public static string? GetUserId(this IIdentity identity)
{
if (identity == null) throw new ArgumentNullException(nameof(identity));
- string userId = null;
+ string? userId = null;
if (identity is ClaimsIdentity claimsIdentity)
{
userId = claimsIdentity.FindFirstValue(ClaimTypes.NameIdentifier)
@@ -48,11 +48,11 @@ namespace Umbraco.Extensions
///
/// The string value of the user name if found otherwise null
///
- public static string GetUserName(this IIdentity identity)
+ public static string? GetUserName(this IIdentity identity)
{
if (identity == null) throw new ArgumentNullException(nameof(identity));
- string username = null;
+ string? username = null;
if (identity is ClaimsIdentity claimsIdentity)
{
username = claimsIdentity.FindFirstValue(ClaimTypes.Name)
@@ -70,7 +70,7 @@ namespace Umbraco.Extensions
///
/// The string value of the claim if found otherwise null
///
- public static string FindFirstValue(this ClaimsIdentity identity, string claimType)
+ public static string? FindFirstValue(this ClaimsIdentity identity, string claimType)
{
if (identity == null) throw new ArgumentNullException(nameof(identity));
@@ -100,7 +100,7 @@ namespace Umbraco.Extensions
///
/// Verified identity wrapped in a ClaimsIdentity with BackOfficeAuthentication type
/// True if ClaimsIdentity
- public static bool VerifyBackOfficeIdentity(this ClaimsIdentity identity, out ClaimsIdentity verifiedIdentity)
+ public static bool VerifyBackOfficeIdentity(this ClaimsIdentity identity, out ClaimsIdentity? verifiedIdentity)
{
if (identity is null)
{
@@ -119,7 +119,7 @@ namespace Umbraco.Extensions
}
}
- verifiedIdentity = identity.AuthenticationType == Constants.Security.BackOfficeAuthenticationType ? identity : new ClaimsIdentity(identity.Claims, Constants.Security.BackOfficeAuthenticationType);
+ verifiedIdentity = identity.AuthenticationType == Constants.Security.BackOfficeAuthenticationType ? identity : new ClaimsIdentity(identity.Claims, Constants.Security.BackOfficeAuthenticationType);
return true;
}
@@ -294,35 +294,44 @@ namespace Umbraco.Extensions
///
///
/// User ID as integer
- public static int GetId(this ClaimsIdentity identity) => int.Parse(identity.FindFirstValue(ClaimTypes.NameIdentifier), CultureInfo.InvariantCulture);
+ public static int? GetId(this ClaimsIdentity identity)
+ {
+ var firstValue = identity.FindFirstValue(ClaimTypes.NameIdentifier);
+ if (firstValue is not null)
+ {
+ int.Parse(firstValue, CultureInfo.InvariantCulture);
+ }
+
+ return null;
+ }
///
/// Get the real name belonging to the user from a ClaimsIdentity
///
///
/// Real name of the user
- public static string GetRealName(this ClaimsIdentity identity) => identity.FindFirstValue(ClaimTypes.GivenName);
+ public static string? GetRealName(this ClaimsIdentity identity) => identity.FindFirstValue(ClaimTypes.GivenName);
///
/// Get the username of the user from a ClaimsIdentity
///
///
/// Username of the user
- public static string GetUsername(this ClaimsIdentity identity) => identity.FindFirstValue(ClaimTypes.Name);
+ public static string? GetUsername(this ClaimsIdentity identity) => identity.FindFirstValue(ClaimTypes.Name);
///
/// Get the culture string from a ClaimsIdentity
///
///
/// Culture string
- public static string GetCultureString(this ClaimsIdentity identity) => identity.FindFirstValue(ClaimTypes.Locality);
+ public static string? GetCultureString(this ClaimsIdentity identity) => identity.FindFirstValue(ClaimTypes.Locality);
///
/// Get the security stamp from a ClaimsIdentity
///
///
/// Security stamp
- public static string GetSecurityStamp(this ClaimsIdentity identity) => identity.FindFirstValue(Constants.Security.SecurityStampClaimType);
+ public static string? GetSecurityStamp(this ClaimsIdentity identity) => identity.FindFirstValue(Constants.Security.SecurityStampClaimType);
///
/// Get the roles assigned to a user from a ClaimsIdentity
@@ -336,17 +345,20 @@ namespace Umbraco.Extensions
///
/// Adds or updates and existing claim.
///
- public static void AddOrUpdateClaim(this ClaimsIdentity identity, Claim claim)
+ public static void AddOrUpdateClaim(this ClaimsIdentity identity, Claim? claim)
{
if (identity == null)
{
throw new ArgumentNullException(nameof(identity));
}
- Claim existingClaim = identity.Claims.FirstOrDefault(x => x.Type == claim.Type);
- identity.TryRemoveClaim(existingClaim);
+ if (claim is not null)
+ {
+ Claim? existingClaim = identity.Claims.FirstOrDefault(x => x.Type == claim.Type);
+ identity.TryRemoveClaim(existingClaim);
- identity.AddClaim(claim);
+ identity.AddClaim(claim);
+ }
}
}
}
diff --git a/src/Umbraco.Core/Extensions/ContentVariationExtensions.cs b/src/Umbraco.Core/Extensions/ContentVariationExtensions.cs
index c6d6b2c557..4469683acb 100644
--- a/src/Umbraco.Core/Extensions/ContentVariationExtensions.cs
+++ b/src/Umbraco.Core/Extensions/ContentVariationExtensions.cs
@@ -289,10 +289,10 @@ namespace Umbraco.Extensions
/// Basically, exact is for one content type, or one property type, and !exact is for "all property types" of one content type.
/// Both and can be "*" to indicate "all of them".
///
- public static bool ValidateVariation(this ContentVariation variation, string culture, string segment, bool exact, bool wildcards, bool throwIfInvalid)
+ public static bool ValidateVariation(this ContentVariation variation, string? culture, string? segment, bool exact, bool wildcards, bool throwIfInvalid)
{
- culture = culture.NullOrWhiteSpaceAsNull();
- segment = segment.NullOrWhiteSpaceAsNull();
+ culture = culture?.NullOrWhiteSpaceAsNull();
+ segment = segment?.NullOrWhiteSpaceAsNull();
// if wildcards are disabled, do not allow "*"
if (!wildcards && (culture == "*" || segment == "*"))
diff --git a/src/Umbraco.Core/Extensions/DelegateExtensions.cs b/src/Umbraco.Core/Extensions/DelegateExtensions.cs
index 43e3c8947b..40ee011641 100644
--- a/src/Umbraco.Core/Extensions/DelegateExtensions.cs
+++ b/src/Umbraco.Core/Extensions/DelegateExtensions.cs
@@ -10,7 +10,7 @@ namespace Umbraco.Extensions
{
public static class DelegateExtensions
{
- public static Attempt RetryUntilSuccessOrTimeout(this Func> task, TimeSpan timeout, TimeSpan pause)
+ public static Attempt RetryUntilSuccessOrTimeout(this Func> task, TimeSpan timeout, TimeSpan pause)
{
if (pause.TotalMilliseconds < 0)
{
@@ -20,14 +20,14 @@ namespace Umbraco.Extensions
do
{
var result = task();
- if (result) { return result; }
+ if (result.Success.HasValue && result.Success.Value) { return result; }
Thread.Sleep((int)pause.TotalMilliseconds);
}
while (stopwatch.Elapsed < timeout);
- return Attempt.Fail();
+ return Attempt.Fail();
}
- public static Attempt RetryUntilSuccessOrMaxAttempts(this Func> task, int totalAttempts, TimeSpan pause)
+ public static Attempt RetryUntilSuccessOrMaxAttempts(this Func> task, int totalAttempts, TimeSpan pause)
{
if (pause.TotalMilliseconds < 0)
{
@@ -38,11 +38,11 @@ namespace Umbraco.Extensions
{
attempts++;
var result = task(attempts);
- if (result) { return result; }
+ if (result.Success.HasValue && result.Success.Value) { return result; }
Thread.Sleep((int)pause.TotalMilliseconds);
}
while (attempts < totalAttempts);
- return Attempt.Fail();
+ return Attempt.Fail();
}
}
}
diff --git a/src/Umbraco.Core/Extensions/DictionaryExtensions.cs b/src/Umbraco.Core/Extensions/DictionaryExtensions.cs
index 6227d506f3..906f12282e 100644
--- a/src/Umbraco.Core/Extensions/DictionaryExtensions.cs
+++ b/src/Umbraco.Core/Extensions/DictionaryExtensions.cs
@@ -53,8 +53,9 @@ namespace Umbraco.Extensions
/// If there is an item in the dictionary with the key, it will keep trying to update it until it can
///
public static bool TryUpdate(this ConcurrentDictionary dict, TKey key, Func updateFactory)
+ where TKey : notnull
{
- TValue curValue;
+ TValue? curValue;
while (dict.TryGetValue(key, out curValue))
{
if (dict.TryUpdate(key, updateFactory(curValue), curValue))
@@ -80,8 +81,9 @@ namespace Umbraco.Extensions
/// WARNING: If the value changes after we've retrieved it, then the item will not be updated
///
public static bool TryUpdateOptimisitic(this ConcurrentDictionary dict, TKey key, Func updateFactory)
+ where TKey : notnull
{
- TValue curValue;
+ TValue? curValue;
if (!dict.TryGetValue(key, out curValue))
return false;
dict.TryUpdate(key, updateFactory(curValue), curValue);
@@ -96,11 +98,12 @@ namespace Umbraco.Extensions
///
///
public static IDictionary ConvertTo(this IDictionary d)
+ where TKeyOut : notnull
{
var result = new Dictionary();
foreach (DictionaryEntry v in d)
{
- result.Add((TKeyOut)v.Key, (TValOut)v.Value);
+ result.Add((TKeyOut)v.Key, (TValOut)v.Value!);
}
return result;
}
@@ -115,11 +118,12 @@ namespace Umbraco.Extensions
///
///
public static IDictionary ConvertTo(this IDictionary d, Func