diff --git a/.github/workflows/publish-cloudsmith.yml b/.github/workflows/publish-cloudsmith.yml
index c92bc592..e6203dce 100644
--- a/.github/workflows/publish-cloudsmith.yml
+++ b/.github/workflows/publish-cloudsmith.yml
@@ -8,7 +8,7 @@ on:
jobs:
publish-nuget:
name: Publish to Cloudsmith
- uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@dev
+ uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@issue/OSOE-925
with:
source: https://nuget.cloudsmith.io/lombiq/open-source-orchard-core-extensions/v3/index.json
secrets:
diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml
index 44a74afd..2b2a5e73 100644
--- a/.github/workflows/publish-nuget.yml
+++ b/.github/workflows/publish-nuget.yml
@@ -9,6 +9,6 @@ jobs:
publish-nuget:
name: Publish to NuGet
if: ${{ !contains(github.ref_name, '-preview.') }}
- uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@dev
+ uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@issue/OSOE-925
secrets:
API_KEY: ${{ secrets.DEFAULT_NUGET_PUBLISH_API_KEY }}
diff --git a/.github/workflows/validate-nuget-publish.yml b/.github/workflows/validate-nuget-publish.yml
index 9f8979c5..f0fd6be1 100644
--- a/.github/workflows/validate-nuget-publish.yml
+++ b/.github/workflows/validate-nuget-publish.yml
@@ -9,4 +9,4 @@ on:
jobs:
validate-nuget-publish:
name: Validate NuGet Publish
- uses: Lombiq/GitHub-Actions/.github/workflows/validate-nuget-publish.yml@dev
+ uses: Lombiq/GitHub-Actions/.github/workflows/validate-nuget-publish.yml@issue/OSOE-925
diff --git a/Lombiq.HelpfulLibraries.AspNetCore/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.AspNetCore/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.AspNetCore/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ForwardedHeadersApplicationBuilderExtensions.cs b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ForwardedHeadersApplicationBuilderExtensions.cs
index 97443767..0a0d6356 100644
--- a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ForwardedHeadersApplicationBuilderExtensions.cs
+++ b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ForwardedHeadersApplicationBuilderExtensions.cs
@@ -32,7 +32,7 @@ public static IApplicationBuilder UseForwardedHeadersForCloudflareAndAzure(this
};
// These are not all known for Cloudflare and Azure.
- forwardedHeadersOptions.KnownNetworks.Clear();
+ forwardedHeadersOptions.KnownIPNetworks.Clear();
forwardedHeadersOptions.KnownProxies.Clear();
builder.UseForwardedHeaders(forwardedHeadersOptions);
diff --git a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/HttpRequestExtensions.cs b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/HttpRequestExtensions.cs
index 14e7c2c5..2d48580b 100644
--- a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/HttpRequestExtensions.cs
+++ b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/HttpRequestExtensions.cs
@@ -114,4 +114,27 @@ public static bool IsAction(
string? area = null)
where TController : ControllerBase =>
request.IsAction(actionSelector.StripResult(), area);
+
+ ///
+ /// If the has a form body, it tries to find the value for amd
+ /// trims it. If that fails or if the result is an empty string, is returned instead.
+ ///
+ public static string? GetFormValueMaybe(this HttpRequest request, string key)
+ {
+ if (!request.HasFormContentType) return null;
+
+ // We use try-catch in case the request is somehow broken or invalid because then just accessing the form can
+ // throw an exception.
+ try
+ {
+ return request.Form.TryGetValue(key, out var values) &&
+ values.WhereNot(string.IsNullOrWhiteSpace).FirstOrDefault()?.Trim() is { } value
+ ? value
+ : null;
+ }
+ catch
+ {
+ return null;
+ }
+ }
}
diff --git a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ServiceCollectionExtensions.cs b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ServiceCollectionExtensions.cs
index dedf02d3..5bdc9f54 100644
--- a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ServiceCollectionExtensions.cs
+++ b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ServiceCollectionExtensions.cs
@@ -11,5 +11,5 @@ public static class ServiceCollectionExtensions
///
public static void AddAsyncResultFilter(this IServiceCollection services)
where TFilter : IAsyncResultFilter =>
- services.Configure(options => options.Filters.Add(typeof(TFilter)));
+ services.Configure(options => options.Filters.Add());
}
diff --git a/Lombiq.HelpfulLibraries.AspNetCore/Lombiq.HelpfulLibraries.AspNetCore.csproj b/Lombiq.HelpfulLibraries.AspNetCore/Lombiq.HelpfulLibraries.AspNetCore.csproj
index 883d918b..95aa6abb 100644
--- a/Lombiq.HelpfulLibraries.AspNetCore/Lombiq.HelpfulLibraries.AspNetCore.csproj
+++ b/Lombiq.HelpfulLibraries.AspNetCore/Lombiq.HelpfulLibraries.AspNetCore.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
diff --git a/Lombiq.HelpfulLibraries.Attributes/Lombiq.HelpfulLibraries.Attributes.csproj b/Lombiq.HelpfulLibraries.Attributes/Lombiq.HelpfulLibraries.Attributes.csproj
index 461e8356..7b29f155 100644
--- a/Lombiq.HelpfulLibraries.Attributes/Lombiq.HelpfulLibraries.Attributes.csproj
+++ b/Lombiq.HelpfulLibraries.Attributes/Lombiq.HelpfulLibraries.Attributes.csproj
@@ -4,7 +4,7 @@
netstandard2.0
true
enable
- latest
+ 14.0
diff --git a/Lombiq.HelpfulLibraries.Cli/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.Cli/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.Cli/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.Cli/Extensions/CommandExtensions.cs b/Lombiq.HelpfulLibraries.Cli/Extensions/CommandExtensions.cs
index cc7b857d..17f37197 100644
--- a/Lombiq.HelpfulLibraries.Cli/Extensions/CommandExtensions.cs
+++ b/Lombiq.HelpfulLibraries.Cli/Extensions/CommandExtensions.cs
@@ -29,16 +29,15 @@ public static async Task ExecuteUntilOutputAsync(
Action? stdErrHandler = default,
CancellationToken cancellationToken = default)
{
- await using var enumerator = command.ListenAsync(cancellationToken).GetAsyncEnumerator(cancellationToken);
-
- while (await enumerator.MoveNextAsync(cancellationToken))
+ await foreach (var commandEvent in command.ListenAsync(cancellationToken))
{
- if (enumerator.Current is StandardOutputCommandEvent stdOut && stdOut.Text.ContainsOrdinalIgnoreCase(outputToWaitFor))
+ if (commandEvent is StandardOutputCommandEvent stdOut &&
+ stdOut.Text.ContainsOrdinalIgnoreCase(outputToWaitFor))
{
return;
}
- if (enumerator.Current is StandardErrorCommandEvent stdErr)
+ if (commandEvent is StandardErrorCommandEvent stdErr)
{
stdErrHandler?.Invoke(stdErr);
}
diff --git a/Lombiq.HelpfulLibraries.Cli/Lombiq.HelpfulLibraries.Cli.csproj b/Lombiq.HelpfulLibraries.Cli/Lombiq.HelpfulLibraries.Cli.csproj
index 9db687c4..e2cff183 100644
--- a/Lombiq.HelpfulLibraries.Cli/Lombiq.HelpfulLibraries.Cli.csproj
+++ b/Lombiq.HelpfulLibraries.Cli/Lombiq.HelpfulLibraries.Cli.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
enable
diff --git a/Lombiq.HelpfulLibraries.Common/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.Common/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.Common/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.Common/Extensions/ArrayExtensions.cs b/Lombiq.HelpfulLibraries.Common/Extensions/ArrayExtensions.cs
index fc6faac7..de3add81 100644
--- a/Lombiq.HelpfulLibraries.Common/Extensions/ArrayExtensions.cs
+++ b/Lombiq.HelpfulLibraries.Common/Extensions/ArrayExtensions.cs
@@ -11,7 +11,7 @@ public static class ArrayExtensions
/// it's better to use this instead of the general `Any()` extension method.
///
///
- public static bool Exists(this T?[] array, Predicate match) => Array.Exists(array, match);
+ public static bool Exists(this T[] array, Predicate match) => Array.Exists(array, match);
///
/// A fluid alternative to .
@@ -22,12 +22,12 @@ public static class ArrayExtensions
/// it's better to use this instead of the general `FirstOrDefault()` extension method.
///
///
- public static T? Find(this T?[] array, Predicate match) => Array.Find(array, match);
+ public static T? Find(this T[] array, Predicate match) => Array.Find(array, match);
///
/// A fluid alternative to .
///
- public static T?[] FindAll(this T?[] array, Predicate match) => Array.FindAll(array, match);
+ public static T[] FindAll(this T[] array, Predicate match) => Array.FindAll(array, match);
///
/// A fluid alternative to .
@@ -38,5 +38,5 @@ public static class ArrayExtensions
/// it's better to use this instead of the general `All()` extension method.
///
///
- public static bool TrueForAll(this T?[] array, Predicate match) => Array.TrueForAll(array, match);
+ public static bool TrueForAll(this T[] array, Predicate match) => Array.TrueForAll(array, match);
}
diff --git a/Lombiq.HelpfulLibraries.Common/Extensions/EnumerableExtensions.cs b/Lombiq.HelpfulLibraries.Common/Extensions/EnumerableExtensions.cs
index 14f723c4..0945086b 100644
--- a/Lombiq.HelpfulLibraries.Common/Extensions/EnumerableExtensions.cs
+++ b/Lombiq.HelpfulLibraries.Common/Extensions/EnumerableExtensions.cs
@@ -93,7 +93,7 @@ public static async Task AwaitEachAsync(
}
///
- /// Awaits the tasks sequentially while the action returns .
+ /// Awaits the tasks sequentially while the action returns .
///
/// if the was never broken.
public static async Task AwaitWhileAsync(
diff --git a/Lombiq.HelpfulLibraries.Common/Extensions/StringExtensions.cs b/Lombiq.HelpfulLibraries.Common/Extensions/StringExtensions.cs
index 397f9cbb..e20e2fe6 100644
--- a/Lombiq.HelpfulLibraries.Common/Extensions/StringExtensions.cs
+++ b/Lombiq.HelpfulLibraries.Common/Extensions/StringExtensions.cs
@@ -98,6 +98,12 @@ public static string[] SplitByNewLines(this string? text) =>
public static bool ContainsLoose(this string? text, string? toFind) =>
text != null && toFind != null && text.Contains(toFind, StringComparison.InvariantCultureIgnoreCase);
+ ///
+ /// A shortcut for string.Equals(string, StringComparison.Ordinal).
+ ///
+ public static bool EqualsOrdinal(this string? text, string? value) =>
+ text?.Equals(value, StringComparison.Ordinal) == true;
+
///
/// A shortcut for string.Equals(string, StringComparison.OrdinalIgnoreCase).
///
@@ -435,4 +441,11 @@ public static string Concat(this string text, IList ranges)
///
public static string Join(this IList ranges, string text) => text.Concat(ranges);
+
+ ///
+ /// Returns if the is or whitespace. This
+ /// makes chaining with the null-coalescing operator (??) easier.
+ ///
+ public static string? NullIfWhiteSpace(this string value) =>
+ string.IsNullOrWhiteSpace(value) ? null : value;
}
diff --git a/Lombiq.HelpfulLibraries.Common/Extensions/ZipArchiveExtensions.cs b/Lombiq.HelpfulLibraries.Common/Extensions/ZipArchiveExtensions.cs
index c556a5e0..a210856d 100644
--- a/Lombiq.HelpfulLibraries.Common/Extensions/ZipArchiveExtensions.cs
+++ b/Lombiq.HelpfulLibraries.Common/Extensions/ZipArchiveExtensions.cs
@@ -10,7 +10,7 @@ public static class ZipArchiveExtensions
///
public static async Task CreateTextEntryAsync(this ZipArchive zip, string entryName, IEnumerable? lines)
{
- await using var writer = new StreamWriter(zip.CreateEntry(entryName).Open());
+ await using var writer = new StreamWriter(await zip.CreateEntry(entryName).OpenAsync());
if (lines == null) return;
@@ -31,7 +31,7 @@ public static Task CreateTextEntryAsync(this ZipArchive zip, string entryName, s
///
public static async Task CreateBinaryEntryAsync(this ZipArchive zip, string entryName, ReadOnlyMemory data)
{
- await using var stream = zip.CreateEntry(entryName).Open();
+ await using var stream = await zip.CreateEntry(entryName).OpenAsync();
await stream.WriteAsync(data);
}
}
diff --git a/Lombiq.HelpfulLibraries.Common/Lombiq.HelpfulLibraries.Common.csproj b/Lombiq.HelpfulLibraries.Common/Lombiq.HelpfulLibraries.Common.csproj
index 27c5aa88..864ad2fb 100644
--- a/Lombiq.HelpfulLibraries.Common/Lombiq.HelpfulLibraries.Common.csproj
+++ b/Lombiq.HelpfulLibraries.Common/Lombiq.HelpfulLibraries.Common.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
@@ -25,9 +25,8 @@
-
-
-
+
+
diff --git a/Lombiq.HelpfulLibraries.LinqToDb/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.LinqToDb/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.LinqToDb/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.LinqToDb/Lombiq.HelpfulLibraries.LinqToDb.csproj b/Lombiq.HelpfulLibraries.LinqToDb/Lombiq.HelpfulLibraries.LinqToDb.csproj
index c38f4763..d2aeac0e 100644
--- a/Lombiq.HelpfulLibraries.LinqToDb/Lombiq.HelpfulLibraries.LinqToDb.csproj
+++ b/Lombiq.HelpfulLibraries.LinqToDb/Lombiq.HelpfulLibraries.LinqToDb.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
@@ -25,6 +25,6 @@
-
+
diff --git a/Lombiq.HelpfulLibraries.OrchardCore.Testing/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.OrchardCore.Testing/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.OrchardCore.Testing/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.OrchardCore.Testing/Lombiq.HelpfulLibraries.OrchardCore.Testing.csproj b/Lombiq.HelpfulLibraries.OrchardCore.Testing/Lombiq.HelpfulLibraries.OrchardCore.Testing.csproj
index 4d9a7f55..65d5818b 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore.Testing/Lombiq.HelpfulLibraries.OrchardCore.Testing.csproj
+++ b/Lombiq.HelpfulLibraries.OrchardCore.Testing/Lombiq.HelpfulLibraries.OrchardCore.Testing.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
@@ -24,7 +24,7 @@
-
+
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.OrchardCore/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.OrchardCore/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonContentDisplayTypes.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonContentDisplayTypes.cs
index fbe43af9..a71c4733 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonContentDisplayTypes.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonContentDisplayTypes.cs
@@ -4,7 +4,7 @@ namespace Lombiq.HelpfulLibraries.OrchardCore.Contents;
///
/// Values that can be used with or to safely select the correct display type.
+/// cref="ContentOrchardRazorHelperExtensions.DisplayAsync"/> to safely select the correct display type.
///
public static class CommonContentDisplayTypes
{
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentEnumerableExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentEnumerableExtensions.cs
index 12808fc4..ca6ad13a 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentEnumerableExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentEnumerableExtensions.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
namespace OrchardCore.ContentManagement;
@@ -8,7 +9,16 @@ public static class ContentEnumerableExtensions
/// Retrieves an enumeration of a content part based on its type from an enumeration of content items.
///
/// The content part enumeration or empty enumeration if it doesn't exist.
+ [Obsolete($"Use {nameof(GetOrCreate)} instead.")]
public static IEnumerable As(this IEnumerable? contents)
where TPart : ContentPart =>
(contents?.SelectWhere(content => content.As())).EmptyIfNull();
+
+ ///
+ /// Retrieves an enumeration of a content part based on its type from an enumeration of content items.
+ ///
+ /// The content part enumeration or empty enumeration if it doesn't exist.
+ public static IEnumerable GetOrCreate(this IEnumerable? contents)
+ where TPart : ContentPart, new() =>
+ (contents?.SelectWhere(content => content.GetMaybe())).EmptyIfNull();
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentExtensions.cs
index 50a9d3c5..5befb95a 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentExtensions.cs
@@ -16,10 +16,20 @@ public static class ContentExtensions
/// Gets a content part by its type.
///
/// The content part or if it doesn't exist.
+ [Obsolete($"Use {nameof(GetOrCreate)} instead.")]
public static TPart? As(this IContent content)
where TPart : ContentPart =>
content.ContentItem.As();
+ ///
+ /// Gets a content part by its type or create a new one.
+ ///
+ /// The type of the content part.
+ /// The content part instance or a new one if it doesn't exist.
+ public static TPart? GetMaybe(this IContent? content)
+ where TPart : ContentPart, new() =>
+ content?.ContentItem?.TryGet(out var part) == true ? part : null;
+
///
/// Gets a content part by its type or create a new one.
///
@@ -129,7 +139,7 @@ public static async Task SanitizeContentItemVersionsAsync(this IContent content,
///
/// Content item containing .
/// Alias of the content item.
- public static string? GetAlias(this IContent content) => content.As()?.Alias;
+ public static string? GetAlias(this IContent content) => content.GetMaybe()?.Alias;
///
/// Provides the most essential data for a enough to identify it in a text format. Can be
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentManagerExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentManagerExtensions.cs
index 53219855..5cf9dd09 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentManagerExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentManagerExtensions.cs
@@ -15,7 +15,7 @@ public static class ContentManagerExtensions
/// The version data of the content item to retrieve.
public static async Task GetAsync(this IContentManager contentManager, string id, VersionOptions? versionOptions = null)
where T : ContentPart =>
- (await contentManager.GetAsync(id, versionOptions))?.As();
+ (await contentManager.GetAsync(id, versionOptions))?.TryGet(out var result) == true ? result : null;
///
/// Persists the given with a new version if it does not exist yet, or updates it
@@ -54,7 +54,7 @@ public static async Task> GetTaxonomyTermsAsync(
? null
: await contentManager.GetAsync(taxonomyContentItemId);
- return taxonomy?.As()?.Terms ?? [];
+ return taxonomy?.GetOrCreate().Terms ?? [];
}
///
@@ -68,7 +68,7 @@ public static async Task> GetTaxonomyTermsDisplayTex
this IContentManager contentManager,
string taxonomyId) =>
(await contentManager.GetAsync(taxonomyId))
- .As()
+ .GetOrCreate()
.Terms
.ToDictionary(term => term.ContentItemId, term => term.DisplayText);
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs
index 4616e30d..6cb64480 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs
@@ -1,9 +1,9 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.ContentManagement;
+using OrchardCore.DisplayManagement.Extensions;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
@@ -16,30 +16,60 @@ public static class ContentOrchardHelperExtensions
///
/// Gets the given content item's edit URL.
///
- [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns relative URL.")]
+ [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns a relative URL.")]
+ [Obsolete($"Use {nameof(GetItemEditUrlAsync)} instead.")]
public static string GetItemEditUrl(this IOrchardHelper orchardHelper, ContentItem contentItem) =>
orchardHelper.GetItemEditUrl(contentItem.ContentItemId);
///
/// Gets the given content item's edit URL.
///
- [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns relative URL.")]
+ [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns a relative URL.")]
+ [Obsolete($"Use {nameof(GetItemEditUrlAsync)} instead.")]
public static string GetItemEditUrl(this IOrchardHelper orchardHelper, string contentItemId)
{
var urlHelper = orchardHelper.GetUrlHelper();
return urlHelper.EditContentItem(contentItemId);
}
+ ///
+ /// Gets the given content item's edit URL.
+ ///
+ [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns a relative URL.")]
+ public static Task GetItemEditUrlAsync(this IOrchardHelper orchardHelper, ContentItem contentItem) =>
+ orchardHelper.GetItemEditUrlAsync(contentItem.ContentItemId);
+
+ ///
+ /// Gets the given content item's edit URL.
+ ///
+ [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns a relative URL.")]
+ public static async Task GetItemEditUrlAsync(this IOrchardHelper orchardHelper, string contentItemId)
+ {
+ var urlHelper = await orchardHelper.GetUrlHelperAsync();
+ return urlHelper.EditContentItem(contentItemId);
+ }
+
///
/// Gets the given content item's display URL.
///
- [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns relative URL.")]
+ [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns a relative URL.")]
+ [Obsolete($"Use {nameof(GetItemDisplayUrlAsync)} instead.")]
public static string GetItemDisplayUrl(this IOrchardHelper orchardHelper, string contentItemId)
{
var urlHelper = orchardHelper.GetUrlHelper();
return urlHelper.DisplayContentItem(contentItemId);
}
+ ///
+ /// Gets the given content item's display URL.
+ ///
+ [SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "It only returns a relative URL.")]
+ public static async Task GetItemDisplayUrlAsync(this IOrchardHelper orchardHelper, string contentItemId)
+ {
+ var urlHelper = await orchardHelper.GetUrlHelperAsync();
+ return urlHelper.DisplayContentItem(contentItemId);
+ }
+
///
/// Runs a getter delegate to get a content item or loads the item currently viewed via Content Preview.
///
@@ -52,17 +82,11 @@ public static Task GetContentItemOrPreviewAsync(
{
var httpContext = orchardHelper.HttpContext;
- if (httpContext.Request.Method == "POST")
- {
- var previewContentItemId = httpContext.Request.Form["PreviewContentItemId"].ToString();
- if (!string.IsNullOrEmpty(previewContentItemId) &&
- httpContext.RequestServices.GetService() is { } contentManager)
- {
- return contentManager.GetAsync(previewContentItemId);
- }
- }
-
- return contentItemGetter();
+ return httpContext.Request.GetFormValueMaybe("PreviewContentItemId") is { } previewContentItemId &&
+ !string.IsNullOrEmpty(previewContentItemId) &&
+ httpContext.RequestServices.GetService() is { } contentManager
+ ? contentManager.GetAsync(previewContentItemId)
+ : contentItemGetter();
}
///
@@ -84,11 +108,19 @@ public static string Action(
///
/// Constructs a new instance using the current .
///
- public static IUrlHelper GetUrlHelper(this IOrchardHelper orchardHelper)
+ [Obsolete($"Use {nameof(GetUrlHelperAsync)} instead.")]
+ public static IUrlHelper GetUrlHelper(this IOrchardHelper orchardHelper) =>
+ orchardHelper.GetUrlHelperAsync().Result;
+
+ ///
+ /// Constructs a new instance using the current .
+ ///
+ public static async Task GetUrlHelperAsync(this IOrchardHelper orchardHelper)
{
var serviceProvider = orchardHelper.HttpContext.RequestServices;
var urlHelperFactory = serviceProvider.GetRequiredService();
- var actionContext = serviceProvider.GetService()?.ActionContext ??
+
+ var actionContext = await orchardHelper.HttpContext.GetActionContextAsync() ??
throw new InvalidOperationException("Couldn't access the action context.");
return urlHelperFactory.GetUrlHelper(actionContext);
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/CreatingOrUpdatingPartHandler.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/CreatingOrUpdatingPartHandler.cs
new file mode 100644
index 00000000..b31aaf93
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/CreatingOrUpdatingPartHandler.cs
@@ -0,0 +1,23 @@
+using OrchardCore.ContentManagement;
+using OrchardCore.ContentManagement.Handlers;
+using System.Threading.Tasks;
+
+namespace Lombiq.HelpfulLibraries.OrchardCore.Contents;
+
+///
+/// Abstraction over , to assign a common event handler for
+/// both and events. This replicates the behavior of handlers
+/// before OC 3.0 that only used the latter.
+///
+public abstract class CreatingOrUpdatingPartHandler : ContentPartHandler
+ where TPart : ContentPart, new()
+{
+ protected abstract Task CreatingOrUpdatingAsync(TPart part);
+
+ public override Task CreatingAsync(CreateContentContext context, TPart part) =>
+ CreatingOrUpdatingAsync(part);
+
+ public override Task UpdatingAsync(UpdateContentContext context, TPart part) =>
+ CreatingOrUpdatingAsync(part);
+}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/SingleDisplayTypeContentPartDisplayDriver.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/SingleDisplayTypeContentPartDisplayDriver.cs
index 6aba2dc4..d45c8ceb 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/SingleDisplayTypeContentPartDisplayDriver.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/SingleDisplayTypeContentPartDisplayDriver.cs
@@ -66,7 +66,7 @@ public FieldHiderPlacementInfoResolver(IServiceProvider provider) =>
if (placementContext.DisplayType == _driver.DisplayType &&
placementContext.Differentiator?.StartsWithOrdinal($"{typeof(TPart).Name}-") == true)
{
- return new PlacementInfo { Location = "-" };
+ return new PlacementInfo(location: "-");
}
return null;
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/TaxonomyHelper.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/TaxonomyHelper.cs
index cc7bd390..df051b58 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/TaxonomyHelper.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/TaxonomyHelper.cs
@@ -54,7 +54,7 @@ public static IList GetAllChildren(ContentItem? contentItem, bool i
if (contentItem == null) return results;
if (includeSelf) results.Add(contentItem);
- var partTerms = contentItem.As()?.Terms ?? Enumerable.Empty();
+ var partTerms = contentItem.GetOrCreate().Terms ?? Enumerable.Empty();
var itemTerms = contentItem.GetProperty>(nameof(TaxonomyPart.Terms)) ?? Enumerable.Empty();
foreach (var child in partTerms.Concat(itemTerms))
{
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Data/IndexExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Data/IndexExtensions.cs
index eae597ee..ae903265 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Data/IndexExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Data/IndexExtensions.cs
@@ -16,7 +16,7 @@ public static IGroupFor MapFor(
this DescribeContext context,
Func map,
bool latest = true)
- where TPart : ContentPart
+ where TPart : ContentPart, new()
where TIndex : IIndex =>
context.For().Map(map, latest);
@@ -28,9 +28,9 @@ public static IGroupFor Map(
this IMapFor mapFor,
Func mapPartToIndex,
bool latest = true)
- where TPart : ContentPart
+ where TPart : ContentPart, new()
where TIndex : IIndex =>
mapFor
.When(item => item.Has() && (item.Latest || !latest))
- .Map(item => mapPartToIndex(item.As()));
+ .Map(item => mapPartToIndex(item.GetOrCreate()));
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Data/QueryExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Data/QueryExtensions.cs
index 41d6014d..8c6e7471 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Data/QueryExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Data/QueryExtensions.cs
@@ -52,9 +52,9 @@ public static Task> PaginateAsync(
this IQuery query,
int pageIndex = 0,
int count = int.MaxValue)
- where TPart : ContentPart =>
+ where TPart : ContentPart, new() =>
PaginateAsync(query, pageIndex, count)
- .ContinueWith(t => t.Result.As(), TaskScheduler.Default);
+ .ContinueWith(t => t.Result.GetOrCreate(), TaskScheduler.Default);
///
/// Breaks the query up into pages and lists the page using the given zero-based index. If pageIndex is 0 and count
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/DateTime/LocalClockExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/DateTime/LocalClockExtensions.cs
index 8ba82d03..fe37efb0 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/DateTime/LocalClockExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/DateTime/LocalClockExtensions.cs
@@ -48,11 +48,13 @@ public static Task ConvertToUtcAsync(
///
public static async Task LocalizeAndFormatAsync(
this ILocalClock localClock,
- DateTime? dateTimeUtc)
+ DateTime? dateTimeUtc,
+ IFormatProvider? formatProvider = null)
{
if (dateTimeUtc == null) return null;
- return ((DateTime?)(await localClock.ConvertToLocalAsync(dateTime: dateTimeUtc.Value)).DateTime).ToString();
+ var localTime = await localClock.ConvertToLocalAsync(dateTime: dateTimeUtc.Value);
+ return localTime.DateTime.ToString(formatProvider);
}
private static async Task ExecuteInDifferentTimeZoneAsync(HttpContext httpContext, string timeZoneId, Func> asyncAction)
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/DependencyInjection/ServiceCollectionExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/DependencyInjection/ServiceCollectionExtensions.cs
index b3db16ef..7d4ad7d2 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/DependencyInjection/ServiceCollectionExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/DependencyInjection/ServiceCollectionExtensions.cs
@@ -3,6 +3,8 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
+using OrchardCore.Environment.Shell;
+using OrchardCore.Environment.Shell.Descriptor.Models;
using OrchardCore.Modules;
using System;
using System.Threading.Tasks;
@@ -44,4 +46,33 @@ public static IServiceCollection AddInlineStartup(
Func? configureAsync = null,
int order = 0) =>
services.AddSingleton(new InlineStartup(configureServices, configure, configureAsync, order));
+
+ ///
+ /// Enables the provided tenant features, but only for the tenant.
+ ///
+ public static IServiceCollection AddDefaultTenantFeatures(
+ this IServiceCollection services,
+ params string[] featureIds)
+ {
+ foreach (var id in featureIds)
+ {
+ services.AddTransient(sp =>
+ {
+ var shellSettings = sp.GetRequiredService();
+ return shellSettings.Name == ShellSettings.DefaultShellName
+ ? new ShellFeature(id, alwaysEnabled: true)
+ : new();
+ });
+ }
+
+ return services;
+ }
+
+ ///
+ /// Enables the provided tenant features, but only for the tenant.
+ ///
+ public static OrchardCoreBuilder AddDefaultTenantFeatures(
+ this OrchardCoreBuilder builder,
+ params string[] featureIds) =>
+ builder.ConfigureServices(services => services.AddDefaultTenantFeatures(featureIds));
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Docs/Elasticsearch.md b/Lombiq.HelpfulLibraries.OrchardCore/Docs/Elasticsearch.md
index 7f5f609e..6fa793d9 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Docs/Elasticsearch.md
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Docs/Elasticsearch.md
@@ -3,5 +3,5 @@
## Extensions
- `ElasticIndexManagerExtensions`: Adds extension methods for the `ElasticIndexManager` like `DeleteAllIndexesAsync`.
-- `ResponseExtensions`: Adds extension methods for handling response objects from the `IElasticClient` like `ThrowIfFailed`.
-- `ConfigurationExtensions`: Adds extension methods for configuration like `CreateElasticClient`.
+- `ResponseExtensions`: Adds extension methods for handling response objects from the `ElasticsearchClient` like `ThrowIfFailed`.
+- `ConfigurationExtensions`: Adds extension methods for configuration like `CreateElasticsearchClient`.
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ConfigurationExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ConfigurationExtensions.cs
index a22ebf5b..f9bc0355 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ConfigurationExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ConfigurationExtensions.cs
@@ -1,16 +1,33 @@
+using Elastic.Clients.Elasticsearch;
using Microsoft.Extensions.Configuration;
-using Nest;
-using OrchardCore.Search.Elasticsearch.Core.Models;
+using Microsoft.Extensions.Logging.Abstractions;
+using OrchardCore.Elasticsearch.Core.Models;
+using OrchardCore.Elasticsearch.Core.Services;
+using System;
namespace OrchardCore.Environment.Shell.Configuration;
public static class ConfigurationExtensions
{
- public static IElasticClient CreateElasticClient(this IShellConfiguration shellConfiguration)
+ [Obsolete($"Use {nameof(CreateElasticsearchClient)} instead.")]
+ public static ElasticsearchClient CreateElasticClient(this IShellConfiguration shellConfiguration) =>
+ shellConfiguration.CreateElasticsearchClient();
+
+ ///
+ /// Returns a new instance of the client.
+ ///
+ ///
+ /// Same as the code found in .
+ ///
+ public static ElasticsearchClient CreateElasticsearchClient(
+ this IShellConfiguration shellConfiguration,
+ IElasticsearchClientFactory? factory = null)
{
- var configuration = shellConfiguration.GetSection("OrchardCore_Elasticsearch");
- var elasticConfiguration = configuration.Get();
+ factory ??= new ElasticsearchClientFactory(NullLogger.Instance);
+
+ var configuration = shellConfiguration.GetSection(ElasticsearchConnectionOptionsConfigurations.ConfigSectionName);
+ var connectionOptions = configuration.Get();
- return new ElasticClient(elasticConfiguration?.GetConnectionSettings());
+ return connectionOptions == null ? new ElasticsearchClient() : factory.Create(connectionOptions);
}
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticIndexManagerExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticIndexManagerExtensions.cs
index b3d433f2..864b5e2b 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticIndexManagerExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticIndexManagerExtensions.cs
@@ -1,6 +1,8 @@
+using Elastic.Clients.Elasticsearch;
+using System;
using System.Threading.Tasks;
-namespace OrchardCore.Search.Elasticsearch.Core.Services;
+namespace OrchardCore.Elasticsearch.Core.Services;
public static class ElasticIndexManagerExtensions
{
@@ -8,6 +10,7 @@ public static class ElasticIndexManagerExtensions
/// Clear all indexes for the tenant (within the prefix, if there is one) by passing a wildcard
/// character (*) as the index name.
///
- public static Task DeleteAllIndexesAsync(this ElasticIndexManager manager) =>
- manager.DeleteIndex("*");
+ [Obsolete($"Use the equivalent extension method for {nameof(ElasticsearchClient)} instead.")]
+ public static Task DeleteAllIndexesAsync(this ElasticsearchIndexManager manager) =>
+ throw new NotSupportedException($"Use the equivalent extension method for {nameof(ElasticsearchClient)} instead.");
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticsearchClientExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticsearchClientExtensions.cs
new file mode 100644
index 00000000..638b72bc
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticsearchClientExtensions.cs
@@ -0,0 +1,35 @@
+using Elastic.Clients.Elasticsearch.Core;
+using Elastic.Clients.Elasticsearch.IndexManagement;
+using Microsoft.Extensions.Configuration;
+using OrchardCore.Elasticsearch;
+using OrchardCore.Elasticsearch.Core.Services;
+using OrchardCore.Environment.Shell.Configuration;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Elastic.Clients.Elasticsearch;
+
+public static class ElasticIndexManagerExtensions
+{
+ ///
+ /// Clear all indexes for the tenant (within the prefix, if there is one) by passing a wildcard character (*)
+ /// as the index name.
+ ///
+ public static async Task DeleteAllIndexesAsync(this ElasticsearchClient client, string? prefix)
+ {
+ var index = string.IsNullOrWhiteSpace(prefix) ? Indices.All : Indices.Index($"{prefix}_*");
+ var getRequest = new GetIndexRequest(index) { ExpandWildcards = [ExpandWildcard.All], AllowNoIndices = true };
+ var getResponse = (await client.Indices.GetAsync(getRequest)).ThrowIfFailed($"get index \"{index}\"");
+
+ if (getResponse.Indices.Count == 0) return;
+ (await client.Indices.DeleteAsync(getResponse.Indices.Keys.ToArray())).ThrowIfFailed($"delete index \"{index}\"");
+ }
+
+ public static Task DeleteAllIndexesAsync(this ElasticsearchClient client, IShellConfiguration shellConfiguration)
+ {
+ var prefix = shellConfiguration
+ .GetSection(ElasticsearchConnectionOptionsConfigurations.ConfigSectionName)
+ .GetValue(nameof(ElasticsearchOptions.IndexPrefix));
+ return client.DeleteAllIndexesAsync(prefix);
+ }
+}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticsearchIndexProfileStoreExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticsearchIndexProfileStoreExtensions.cs
new file mode 100644
index 00000000..970af9dc
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ElasticsearchIndexProfileStoreExtensions.cs
@@ -0,0 +1,17 @@
+using OrchardCore.Elasticsearch;
+using OrchardCore.Indexing.Models;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace OrchardCore.Indexing;
+
+public static class ElasticsearchIndexProfileStoreExtensions
+{
+ ///
+ /// Returns only the Elasticsearch indexes from the .
+ ///
+ public static async Task> GetAllElasticsearchIndexesAsync(this IIndexProfileStore store) =>
+ (await store.GetAllAsync())
+ .Where(profile => profile.ProviderName == ElasticsearchConstants.ProviderName);
+}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ResponseExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ResponseExtensions.cs
index e1085c38..87b0aae5 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ResponseExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Elasticsearch/ResponseExtensions.cs
@@ -1,13 +1,13 @@
+using Elastic.Transport.Products.Elasticsearch;
using System;
-
-namespace Nest;
+namespace Elastic.Clients.Elasticsearch.Core;
public static class ResponseExtensions
{
public static T ThrowIfFailed(this T response, string? message = null)
- where T : ResponseBase
+ where T : ElasticsearchResponse
{
- if (response.IsValid) return response;
+ if (response.IsValidResponse) return response;
if (!string.IsNullOrWhiteSpace(message)) message = $" ({message.Trim()})";
var error = $"Elasticsearch operation failed{message}. {response.DebugInformation}";
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs
index 7f5ee9dc..d143cb37 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs
@@ -1,3 +1,4 @@
+using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
@@ -122,9 +123,8 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults(
if (webApplicationBuilder.Configuration.IsAzureHosting())
{
builder
- .AddTenantFeatures(
- "OrchardCore.DataProtection.Azure",
- "Lombiq.Hosting.BuildVersionDisplay")
+ .AddDefaultTenantFeatures("Lombiq.Hosting.BuildVersionDisplay")
+ .AddTenantFeatures("OrchardCore.DataProtection.Azure")
.DisableResourceDebugMode();
if (hostingConfiguration.AlwaysEnableAzureMediaStorage)
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/GraphQL/TotalOfContentTypeBuilder.cs b/Lombiq.HelpfulLibraries.OrchardCore/GraphQL/TotalOfContentTypeBuilder.cs
index 035473ff..da9db74b 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/GraphQL/TotalOfContentTypeBuilder.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/GraphQL/TotalOfContentTypeBuilder.cs
@@ -47,4 +47,9 @@ public void Build(ISchema schema, FieldType contentQuery, ContentTypeDefinition
.CountAsync();
});
}
+
+ public void Clear()
+ {
+ // Nothing to do here.
+ }
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Lombiq.HelpfulLibraries.OrchardCore.csproj b/Lombiq.HelpfulLibraries.OrchardCore/Lombiq.HelpfulLibraries.OrchardCore.csproj
index 2d687e7a..c1549197 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Lombiq.HelpfulLibraries.OrchardCore.csproj
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Lombiq.HelpfulLibraries.OrchardCore.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
@@ -24,34 +24,35 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Mvc/MvcActionContextExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Mvc/MvcActionContextExtensions.cs
index f5858921..46df8a5d 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Mvc/MvcActionContextExtensions.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Mvc/MvcActionContextExtensions.cs
@@ -18,13 +18,18 @@ public static bool IsMvcRoute(
string? controller = null,
string? area = null)
{
- var routeValues = context.ActionDescriptor.RouteValues;
+ static bool IsMatch(IDictionary routeValues, string key, string? expected) =>
+ routeValues.TryGetValue(key, out var value) &&
+ (expected?.EqualsOrdinalIgnoreCase(value) ?? value is null);
- if (!string.IsNullOrEmpty(action) && routeValues["Action"]?.EqualsOrdinalIgnoreCase(action) != true) return false;
- if (!string.IsNullOrEmpty(controller) && routeValues["Controller"]?.EqualsOrdinalIgnoreCase(controller) != true) return false;
- if (!string.IsNullOrEmpty(area) && routeValues["Area"]?.EqualsOrdinalIgnoreCase(area) != true) return false;
+ var routeValues = new Dictionary(
+ context.ActionDescriptor.RouteValues,
+ StringComparer.OrdinalIgnoreCase);
- return true;
+ return
+ IsMatch(routeValues, "Action", action) &&
+ IsMatch(routeValues, "Controller", controller) &&
+ IsMatch(routeValues, "Area", area);
}
///
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/ResourceManagement/ResourceFilterBuilder.cs b/Lombiq.HelpfulLibraries.OrchardCore/ResourceManagement/ResourceFilterBuilder.cs
index 913baef1..b8225125 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/ResourceManagement/ResourceFilterBuilder.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/ResourceManagement/ResourceFilterBuilder.cs
@@ -164,12 +164,15 @@ private ResourceFilter WhenContentTypeInner(string displayType, params string[]
}
var session = context.RequestServices.GetRequiredService();
- var query = displayType.EqualsOrdinalIgnoreCase("Edit") ?
- // We check for both published and draft content items.
- session.QueryIndex(index => index.Published || (index.Latest && !index.Published))
+
+ // In case of Edit, we check for both published and draft content items.
+ var query = string.Equals(displayType, "Edit", StringComparison.Ordinal)
+ ? session.QueryIndex(index => index.Published || (index.Latest && !index.Published))
: session.QueryContentItemIndex(PublicationStatus.Published);
- var contentItemIndex = await query.Where(index => index.ContentItemId == contentItemId)
- .FirstOrDefaultAsync();
+
+ var contentItemIndex = await query
+ .Where(index => index.ContentItemId == contentItemId)
+ .FirstOrDefaultAsync(context.RequestAborted);
return contentItemIndex?.ContentType is { } contentType &&
contentTypes.Contains(contentType, StringComparer.OrdinalIgnoreCase);
});
@@ -181,11 +184,9 @@ private static bool GetContentItemId(string displayType, HttpContext context, ou
{
try
{
- if (HttpMethods.IsPost(context.Request.Method)
- && (context.Request.ContentType?.ContainsOrdinalIgnoreCase("application/x-www-form-urlencoded") ?? false)
- && context.Request.Form.TryGetValue("PreviewContentItemId", out var previewContentItemId))
+ if (context.Request.GetFormValueMaybe("PreviewContentItemId") is { } previewContentItemId)
{
- contentItemId = previewContentItemId.FirstOrDefault();
+ contentItemId = previewContentItemId;
return true;
}
@@ -211,7 +212,6 @@ private static bool GetContentItemId(string displayType, HttpContext context, ou
}
contentItemId = null;
-
return false;
}
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Security/ContentSecurityPolicyAttributeContentSecurityPolicyProvider.cs b/Lombiq.HelpfulLibraries.OrchardCore/Security/ContentSecurityPolicyAttributeContentSecurityPolicyProvider.cs
index 2239147d..7241e8c2 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Security/ContentSecurityPolicyAttributeContentSecurityPolicyProvider.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Security/ContentSecurityPolicyAttributeContentSecurityPolicyProvider.cs
@@ -1,10 +1,10 @@
using Lombiq.HelpfulLibraries.AspNetCore.Security;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
-using Microsoft.AspNetCore.Mvc.Infrastructure;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using static Lombiq.HelpfulLibraries.AspNetCore.Security.ContentSecurityPolicyDirectives;
@@ -60,16 +60,22 @@ public class ContentSecurityPolicyAttributeContentSecurityPolicyProvider : ICont
{
public ValueTask UpdateAsync(IDictionary securityPolicies, HttpContext context)
{
- if (context.RequestServices.GetService() is
- { ActionContext.ActionDescriptor: ControllerActionDescriptor actionDescriptor })
+ var actionDescriptor = context
+ .GetEndpoint()?
+ .Metadata
+ .CastWhere()
+ .FirstOrDefault();
+
+ var attributes = actionDescriptor?
+ .MethodInfo
+ .GetCustomAttributes() ?? [];
+
+ foreach (var attribute in attributes)
{
- foreach (var attribute in actionDescriptor.MethodInfo.GetCustomAttributes())
- {
- ContentSecurityPolicyProvider.MergeDirectiveValues(
- securityPolicies,
- attribute.DirectiveNames,
- attribute.DirectiveValue);
- }
+ ContentSecurityPolicyProvider.MergeDirectiveValues(
+ securityPolicies,
+ attribute.DirectiveNames,
+ attribute.DirectiveValue);
}
return ValueTask.CompletedTask;
diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Shapes/PerTenantShapeTableManager.cs b/Lombiq.HelpfulLibraries.OrchardCore/Shapes/PerTenantShapeTableManager.cs
index 55e5c609..aebe61ed 100644
--- a/Lombiq.HelpfulLibraries.OrchardCore/Shapes/PerTenantShapeTableManager.cs
+++ b/Lombiq.HelpfulLibraries.OrchardCore/Shapes/PerTenantShapeTableManager.cs
@@ -9,7 +9,6 @@
using OrchardCore.Environment.Shell;
using OrchardCore.Settings;
using System;
-using System.Collections.Concurrent;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@@ -111,8 +110,6 @@ public async Task GetShapeTableAsync(string themeId)
.Select((id, index) => new { id, index })
.ToDictionary(item => item.id, item => item.index);
- var concurrentShapeDescriptors = new ConcurrentDictionary(shapeDescriptors);
-
// Using the dictionary for O(1) index retrieval instead of O(n) in a list.
var descriptors = shapeDescriptors
.Where(shapeDescriptor => featureIdIndexLookup.ContainsKey(shapeDescriptor.Value.Feature.Id) &&
@@ -121,9 +118,7 @@ public async Task GetShapeTableAsync(string themeId)
.GroupBy(shapeDescriptor => shapeDescriptor.Value.ShapeType, StringComparer.OrdinalIgnoreCase)
.Select(group => new ShapeDescriptorIndex(
shapeType: group.Key,
- alterationKeys: group.Select(kv => kv.Key),
- descriptors: concurrentShapeDescriptors
- ))
+ alterations: group.Select(pair => pair.Value)))
.ToList();
shapeTable = new ShapeTable(
diff --git a/Lombiq.HelpfulLibraries.RestEase/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries.RestEase/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries.RestEase/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.RestEase/Lombiq.HelpfulLibraries.RestEase.csproj b/Lombiq.HelpfulLibraries.RestEase/Lombiq.HelpfulLibraries.RestEase.csproj
index 46919d65..7d13ced6 100644
--- a/Lombiq.HelpfulLibraries.RestEase/Lombiq.HelpfulLibraries.RestEase.csproj
+++ b/Lombiq.HelpfulLibraries.RestEase/Lombiq.HelpfulLibraries.RestEase.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
@@ -24,7 +24,7 @@
-
+
all
diff --git a/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.AssertSimpleQueryAsync.approved.json b/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.AssertSimpleQueryAsync.approved.json
index 76c7f9f1..8b72aa13 100644
--- a/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.AssertSimpleQueryAsync.approved.json
+++ b/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.AssertSimpleQueryAsync.approved.json
@@ -1 +1 @@
-[{"documentId":7,"contentItemId":"","path":"tags/space","published":true,"latest":true,"containedContentItemId":"","jsonPath":"TaxonomyPart.Terms[2]","id":12},{"documentId":7,"contentItemId":"","path":"tags/exploration","published":true,"latest":true,"containedContentItemId":"","jsonPath":"TaxonomyPart.Terms[1]","id":11},{"documentId":7,"contentItemId":"","path":"tags/earth","published":true,"latest":true,"containedContentItemId":"","jsonPath":"TaxonomyPart.Terms[0]","id":10},{"documentId":7,"contentItemId":"","path":"tags","published":true,"latest":true,"containedContentItemId":"","jsonPath":null,"id":9},{"documentId":8,"contentItemId":"","path":"categories/travel","published":true,"latest":true,"containedContentItemId":"","jsonPath":"TaxonomyPart.Terms[0]","id":18},{"documentId":8,"contentItemId":"","path":"categories","published":true,"latest":true,"containedContentItemId":"","jsonPath":null,"id":17},{"documentId":23,"contentItemId":"","path":"carousel-widget-example","published":true,"latest":true,"containedContentItemId":"","jsonPath":null,"id":31},{"documentId":11,"contentItemId":"","path":"about","published":true,"latest":true,"containedContentItemId":"","jsonPath":null,"id":27}]
\ No newline at end of file
+[{"containedContentItemId":"","contentItemId":"","jsonPath":"TaxonomyPart.Terms[2]","latest":true,"path":"tags/space","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":"TaxonomyPart.Terms[1]","latest":true,"path":"tags/exploration","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":"TaxonomyPart.Terms[0]","latest":true,"path":"tags/earth","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":null,"latest":true,"path":"tags","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":"TaxonomyPart.Terms[0]","latest":true,"path":"categories/travel","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":null,"latest":true,"path":"categories","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":null,"latest":true,"path":"carousel-widget-example","published":true},{"containedContentItemId":"","contentItemId":"","jsonPath":null,"latest":true,"path":"about","published":true}]
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs b/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs
index c9f8d379..41e7f14b 100644
--- a/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs
+++ b/Lombiq.HelpfulLibraries.Samples.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs
@@ -4,6 +4,8 @@
using Lombiq.Tests.UI.Services;
using Shouldly;
using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Nodes;
@@ -28,8 +30,22 @@ private static async Task AssertSimpleQueryAsync(UITestContext context, HttpClie
{
var simpleQueryUrl = context.GetAbsoluteUrlOfAction(controller => controller.SimpleQuery());
var simpleQueryOutput = await client.GetStringAsync(simpleQueryUrl, context.Configuration.TestCancellationToken);
+ var simpleQueryParsed = JsonSerializer.Deserialize>>(simpleQueryOutput);
- simpleQueryOutput.ShouldMatchApproved(
+ // Cleanup received data.
+ simpleQueryParsed = simpleQueryParsed
+ .Select(item => item
+ // The "id" and "documentId" properties depend on the record's write order in the database. They are not
+ // guaranteed to be consistent on different setups, and they are not relevant for this query.
+ .Where(pair => pair.Key is not "id" and not "documentId")
+ // The order of these properties is not guaranteed either, so sorting them here makes it more reliable.
+ .OrderBy(pair => pair.Key)
+ .ToDictionary(pair => pair.Key, pair => pair.Value))
+ .ToList();
+
+ // The results are re-serialized into JSON using standard options, so they can be compared in a consistent way.
+ var reserialized = JsonSerializer.Serialize(simpleQueryParsed, JOptions.Default);
+ reserialized.ShouldMatchApproved(
options => options
.WithScrubber(ScrubContentItemIds)
.WithFileExtension("json"),
diff --git a/Lombiq.HelpfulLibraries.Samples.Tests.UI/Lombiq.HelpfulLibraries.Samples.Tests.UI.csproj b/Lombiq.HelpfulLibraries.Samples.Tests.UI/Lombiq.HelpfulLibraries.Samples.Tests.UI.csproj
index ef468d17..e1bde716 100644
--- a/Lombiq.HelpfulLibraries.Samples.Tests.UI/Lombiq.HelpfulLibraries.Samples.Tests.UI.csproj
+++ b/Lombiq.HelpfulLibraries.Samples.Tests.UI/Lombiq.HelpfulLibraries.Samples.Tests.UI.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
diff --git a/Lombiq.HelpfulLibraries.Samples/Lombiq.HelpfulLibraries.Samples.csproj b/Lombiq.HelpfulLibraries.Samples/Lombiq.HelpfulLibraries.Samples.csproj
index 1e8e5b82..a1f43b99 100644
--- a/Lombiq.HelpfulLibraries.Samples/Lombiq.HelpfulLibraries.Samples.csproj
+++ b/Lombiq.HelpfulLibraries.Samples/Lombiq.HelpfulLibraries.Samples.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
true
false
$(DefaultItemExcludes);.git*
@@ -12,12 +12,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Lombiq.HelpfulLibraries.SourceGenerators/Lombiq.HelpfulLibraries.SourceGenerators.csproj b/Lombiq.HelpfulLibraries.SourceGenerators/Lombiq.HelpfulLibraries.SourceGenerators.csproj
index 3d4dd97b..b3ab418f 100644
--- a/Lombiq.HelpfulLibraries.SourceGenerators/Lombiq.HelpfulLibraries.SourceGenerators.csproj
+++ b/Lombiq.HelpfulLibraries.SourceGenerators/Lombiq.HelpfulLibraries.SourceGenerators.csproj
@@ -4,7 +4,7 @@
netstandard2.0
true
enable
- latest
+ 14.0
true
true
@@ -34,7 +34,7 @@
-
+
@@ -44,7 +44,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Lombiq.HelpfulLibraries.Tests/Lombiq.HelpfulLibraries.Tests.csproj b/Lombiq.HelpfulLibraries.Tests/Lombiq.HelpfulLibraries.Tests.csproj
index d073cc91..648a6c7c 100644
--- a/Lombiq.HelpfulLibraries.Tests/Lombiq.HelpfulLibraries.Tests.csproj
+++ b/Lombiq.HelpfulLibraries.Tests/Lombiq.HelpfulLibraries.Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
Exe
diff --git a/Lombiq.HelpfulLibraries.Tests/UnitTests/Extensions/SafeJsonTests.cs b/Lombiq.HelpfulLibraries.Tests/UnitTests/Extensions/SafeJsonTests.cs
index 5c1b5dcd..17651618 100644
--- a/Lombiq.HelpfulLibraries.Tests/UnitTests/Extensions/SafeJsonTests.cs
+++ b/Lombiq.HelpfulLibraries.Tests/UnitTests/Extensions/SafeJsonTests.cs
@@ -120,7 +120,7 @@ private static async Task> SafeJsonToDictionaryAsync(
private sealed record TestResults(
ListLoggerProvider LoggerProvider,
- Dictionary Failure,
- Dictionary FailureAsync,
- Dictionary Success);
+ IDictionary Failure,
+ IDictionary FailureAsync,
+ IDictionary Success);
}
diff --git a/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceFixture.cs b/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceFixture.cs
index 0908a0fd..69be30c0 100644
--- a/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceFixture.cs
+++ b/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceFixture.cs
@@ -44,9 +44,9 @@ public async Task SessionAsync(Func action)
{
if (Store == null) await CreateDatabaseAsync();
- await using var session = Store.CreateSession();
+ await using var session = Store!.CreateSession();
await action(session);
- await session.FlushAsync();
+ await session.FlushAsync(Xunit.TestContext.Current.CancellationToken);
}
// We could have a
diff --git a/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceTests.cs b/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceTests.cs
index 8aa64297..088c2c0b 100644
--- a/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceTests.cs
+++ b/Lombiq.HelpfulLibraries.Tests/UnitTests/Services/ManualConnectingIndexServiceTests.cs
@@ -1,6 +1,7 @@
using Lombiq.HelpfulLibraries.Tests.Models;
using Shouldly;
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
@@ -22,12 +23,17 @@ public class ManualConnectingIndexServiceTests : IClassFixture _fixture.SessionAsync(async session =>
{
- var indices = (await session.QueryIndex().ListAsync()).ToList();
+ var indices = (await session.QueryIndex().ListAsync(TestContext.Current.CancellationToken)).ToList();
indices.ShouldNotBeEmpty();
- var documents = (await session.Query().ListAsync())
+ IDictionary documents =
+ (await session.Query().ListAsync(TestContext.Current.CancellationToken))
.ToDictionary(document => document.Name);
- foreach (var index in indices) documents.ShouldContainKey(NamePrefix + index.Number.ToTechnicalString());
+
+ foreach (var index in indices)
+ {
+ documents.ShouldContainKey(NamePrefix + index.Number.ToTechnicalString());
+ }
});
[Fact]
@@ -36,7 +42,7 @@ public Task AllIndexShouldRetrieveItsDocument() => _fixture.SessionAsync(async s
// In the example 3's index was intentionally skipped and 6's index was deleted after the fact.
var numbers = Enumerable.Range(0, 10).Where(i => i is not 3 and not 6).ToList();
var query = session.Query(index => index.Number.IsIn(numbers));
- var list = await query.ListAsync();
+ var list = await query.ListAsync(TestContext.Current.CancellationToken);
var documents = list.ToList();
documents.Select(document => document.Name)
.ShouldBe(_fixture.Documents.Where((_, index) => index is not 3 and not 6).Select(document => document.Name));
@@ -45,7 +51,10 @@ public Task AllIndexShouldRetrieveItsDocument() => _fixture.SessionAsync(async s
[Fact]
public Task MissingOrDeletedIndexShouldNotRetrieveAnyDocument() => _fixture.SessionAsync(async session =>
{
- var documents = (await session.Query(index => index.Number.IsIn(Numbers)).ListAsync()).ToList();
+ var documents = (await session
+ .Query(index => index.Number.IsIn(Numbers))
+ .ListAsync(TestContext.Current.CancellationToken))
+ .AsList();
documents.ShouldBeEmpty();
});
}
diff --git a/Lombiq.HelpfulLibraries/CompatibilitySuppressions.xml b/Lombiq.HelpfulLibraries/CompatibilitySuppressions.xml
new file mode 100644
index 00000000..8af156c8
--- /dev/null
+++ b/Lombiq.HelpfulLibraries/CompatibilitySuppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ PKV006
+ net8.0
+
+
\ No newline at end of file
diff --git a/Lombiq.HelpfulLibraries/Lombiq.HelpfulLibraries.csproj b/Lombiq.HelpfulLibraries/Lombiq.HelpfulLibraries.csproj
index 1f774ddf..5caf0e73 100644
--- a/Lombiq.HelpfulLibraries/Lombiq.HelpfulLibraries.csproj
+++ b/Lombiq.HelpfulLibraries/Lombiq.HelpfulLibraries.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
$(DefaultItemExcludes);.git*
enable
@@ -28,7 +28,6 @@
-
diff --git a/NuGet.config b/NuGet.config
index 2ba9b219..2e8ae60a 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -3,15 +3,7 @@
-
-
-
-
-
-
-
-