diff --git a/Directory.Build.props b/Directory.Build.props
index 4e8f6cd101..5fddbdf8ab 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -52,11 +52,6 @@
$(NoWarn);CA1062
-
-
- $(NoWarn);SYSLIB1006
-
-
diff --git a/JsonApiDotNetCore.sln.DotSettings b/JsonApiDotNetCore.sln.DotSettings
index 5878341db6..7151bb82c8 100644
--- a/JsonApiDotNetCore.sln.DotSettings
+++ b/JsonApiDotNetCore.sln.DotSettings
@@ -14,6 +14,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$);
3000
50
False
+ 83FF097C-C8C6-477B-9FAB-DF99B84978B5/f:ReadOnlySet.cs
SOLUTION
True
True
diff --git a/README.md b/README.md
index 3354eac45b..8bd84b3d9c 100644
--- a/README.md
+++ b/README.md
@@ -87,13 +87,9 @@ See also our [versioning policy](./VERSIONING_POLICY.md).
| | | 7 | 7 |
| | | 8 | 8, 9 |
| | | 9 | 9 |
-| master | Preview | 6 | 6, 7 |
-| | | 7 | 7 |
-| | | 8 | 8, 9 |
+| master | Preview | 8 | 8, 9 |
| | | 9 | 9 |
-| openapi | Experimental | 6 | 6, 7 |
-| | | 7 | 7 |
-| | | 8 | 8, 9 |
+| openapi | Experimental | 8 | 8, 9 |
| | | 9 | 9 |
## Contributing
diff --git a/package-versions.props b/package-versions.props
index b5d2f30cb3..00e8462550 100644
--- a/package-versions.props
+++ b/package-versions.props
@@ -15,6 +15,7 @@
2.4.*
2.0.*
8.0.*
+ 9.0.*
17.11.*
2.9.*
2.8.*
@@ -28,7 +29,6 @@
9.0.*
9.0.*
9.0.0-*
- $(AspNetCoreVersion)
@@ -39,18 +39,5 @@
8.0.*
8.0.*
$(EntityFrameworkCoreVersion)
- $(AspNetCoreVersion)
-
-
-
-
- 6.0.0
-
-
- 6.0.*
- 2.1.*
- 7.0.*
- $(EntityFrameworkCoreVersion)
- 8.0.*
diff --git a/src/Examples/DapperExample/DapperExample.csproj b/src/Examples/DapperExample/DapperExample.csproj
index 2d3fad689d..ed7bd358eb 100644
--- a/src/Examples/DapperExample/DapperExample.csproj
+++ b/src/Examples/DapperExample/DapperExample.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/Examples/DapperExample/Program.cs b/src/Examples/DapperExample/Program.cs
index 31e5814e5b..f68d480564 100644
--- a/src/Examples/DapperExample/Program.cs
+++ b/src/Examples/DapperExample/Program.cs
@@ -31,10 +31,10 @@
}
case DatabaseProvider.MySql:
{
-#if NET9_0_OR_GREATER
- ServerVersion serverVersion = await ServerVersion.AutoDetectAsync(connectionString);
-#else
+#if NET8_0
ServerVersion serverVersion = ServerVersion.AutoDetect(connectionString);
+#else
+ ServerVersion serverVersion = await ServerVersion.AutoDetectAsync(connectionString);
#endif
builder.Services.AddMySql(connectionString, serverVersion, optionsAction: options => SetDbContextDebugOptions(options));
diff --git a/src/Examples/DapperExample/Repositories/ResultSetMapper.cs b/src/Examples/DapperExample/Repositories/ResultSetMapper.cs
index 1b20f74dd9..89a7890fd0 100644
--- a/src/Examples/DapperExample/Repositories/ResultSetMapper.cs
+++ b/src/Examples/DapperExample/Repositories/ResultSetMapper.cs
@@ -3,9 +3,6 @@
using JsonApiDotNetCore.Queries.Expressions;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Resources.Annotations;
-#if NET6_0
-using JsonApiDotNetCore;
-#endif
namespace DapperExample.Repositories;
diff --git a/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj b/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj
index a22b938ba0..3edc993428 100644
--- a/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj
+++ b/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/Examples/GettingStarted/GettingStarted.csproj b/src/Examples/GettingStarted/GettingStarted.csproj
index 22fc0529b1..611aeb37a5 100644
--- a/src/Examples/GettingStarted/GettingStarted.csproj
+++ b/src/Examples/GettingStarted/GettingStarted.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs
index cd85ccd696..aab9369618 100644
--- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs
+++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs
@@ -5,28 +5,14 @@
using JsonApiDotNetCore.Queries.Expressions;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCoreExample.Models;
-#if NET6_0
-using Microsoft.AspNetCore.Authentication;
-#endif
namespace JsonApiDotNetCoreExample.Definitions;
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
-public sealed class TodoItemDefinition(
- IResourceGraph resourceGraph,
-#if NET6_0
- ISystemClock systemClock
-#else
- TimeProvider timeProvider
-#endif
-)
+public sealed class TodoItemDefinition(IResourceGraph resourceGraph, TimeProvider timeProvider)
: JsonApiResourceDefinition(resourceGraph)
{
-#if NET6_0
- private readonly Func _getUtcNow = () => systemClock.UtcNow;
-#else
private readonly Func _getUtcNow = timeProvider.GetUtcNow;
-#endif
public override SortExpression OnApplySort(SortExpression? existingSort)
{
diff --git a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
index a22b938ba0..3edc993428 100644
--- a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
+++ b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/Examples/JsonApiDotNetCoreExample/Program.cs b/src/Examples/JsonApiDotNetCoreExample/Program.cs
index 4c11a71660..2cfa1e640d 100644
--- a/src/Examples/JsonApiDotNetCoreExample/Program.cs
+++ b/src/Examples/JsonApiDotNetCoreExample/Program.cs
@@ -8,9 +8,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection.Extensions;
-#if NET6_0
-using Microsoft.AspNetCore.Authentication;
-#endif
[assembly: ExcludeFromCodeCoverage]
@@ -48,11 +45,7 @@ static void ConfigureServices(WebApplicationBuilder builder)
{
using IDisposable _ = CodeTimingSessionManager.Current.Measure("Configure services");
-#if NET6_0
- builder.Services.TryAddSingleton();
-#else
builder.Services.TryAddSingleton(TimeProvider.System);
-#endif
builder.Services.AddDbContext(options =>
{
diff --git a/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj b/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj
index 22fc0529b1..611aeb37a5 100644
--- a/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj
+++ b/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj b/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj
index c45552dc2d..15a485c08f 100644
--- a/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj
+++ b/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/Examples/NoEntityFrameworkExample/Repositories/InMemoryResourceRepository.cs b/src/Examples/NoEntityFrameworkExample/Repositories/InMemoryResourceRepository.cs
index 9eba0b8326..4feb370858 100644
--- a/src/Examples/NoEntityFrameworkExample/Repositories/InMemoryResourceRepository.cs
+++ b/src/Examples/NoEntityFrameworkExample/Repositories/InMemoryResourceRepository.cs
@@ -32,11 +32,7 @@ public Task> GetAsync(QueryLayer queryLayer, Canc
IEnumerable dataSource = GetDataSource();
IEnumerable resources = _queryLayerToLinqConverter.ApplyQueryLayer(queryLayer, dataSource);
-#if NET6_0
- return Task.FromResult>(Array.AsReadOnly(resources.ToArray()));
-#else
return Task.FromResult>(resources.ToArray().AsReadOnly());
-#endif
}
///
diff --git a/src/Examples/NoEntityFrameworkExample/Services/InMemoryResourceService.cs b/src/Examples/NoEntityFrameworkExample/Services/InMemoryResourceService.cs
index e55b9340b6..0dcc5d9905 100644
--- a/src/Examples/NoEntityFrameworkExample/Services/InMemoryResourceService.cs
+++ b/src/Examples/NoEntityFrameworkExample/Services/InMemoryResourceService.cs
@@ -65,11 +65,7 @@ public Task> GetAsync(CancellationToken cancellat
_paginationContext.IsPageFull = true;
}
-#if NET6_0
- return Task.FromResult>(Array.AsReadOnly(resources));
-#else
return Task.FromResult>(resources.AsReadOnly());
-#endif
}
private void LogFiltersInTopScope()
diff --git a/src/Examples/ReportsExample/ReportsExample.csproj b/src/Examples/ReportsExample/ReportsExample.csproj
index 3f2c288b23..6ade1386be 100644
--- a/src/Examples/ReportsExample/ReportsExample.csproj
+++ b/src/Examples/ReportsExample/ReportsExample.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/src/JsonApiDotNetCore.Annotations/ArgumentGuard.cs b/src/JsonApiDotNetCore.Annotations/ArgumentGuard.cs
index e01b80d776..137654fb3e 100644
--- a/src/JsonApiDotNetCore.Annotations/ArgumentGuard.cs
+++ b/src/JsonApiDotNetCore.Annotations/ArgumentGuard.cs
@@ -30,30 +30,12 @@ public static void NotNullNorEmpty([SysNotNull] IEnumerable? value, [Calle
[AssertionMethod]
public static void NotNullNorEmpty([SysNotNull] string? value, [CallerArgumentExpression(nameof(value))] string? parameterName = null)
{
-#if !NET6_0
ArgumentException.ThrowIfNullOrEmpty(value, parameterName);
-#else
- ArgumentNullException.ThrowIfNull(value, parameterName);
-
- if (value.Length == 0)
- {
- throw new ArgumentException("String cannot be null or empty.", parameterName);
- }
-#endif
}
[AssertionMethod]
public static void NotNullNorWhitespace([SysNotNull] string? value, [CallerArgumentExpression(nameof(value))] string? parameterName = null)
{
-#if !NET6_0
ArgumentException.ThrowIfNullOrWhiteSpace(value, parameterName);
-#else
- ArgumentNullException.ThrowIfNull(value, parameterName);
-
- if (string.IsNullOrWhiteSpace(value))
- {
- throw new ArgumentException("String cannot be null, empty, or whitespace.", parameterName);
- }
-#endif
}
}
diff --git a/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj b/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj
index 04238621da..09968a0922 100644
--- a/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj
+++ b/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj
@@ -1,6 +1,6 @@
- net8.0;net6.0;netstandard1.0
+ net8.0;netstandard1.0
true
true
JsonApiDotNetCore
diff --git a/src/JsonApiDotNetCore.Annotations/PolyfillCollectionExtensions.cs b/src/JsonApiDotNetCore.Annotations/PolyfillCollectionExtensions.cs
index 72578e5db2..efc51f4f17 100644
--- a/src/JsonApiDotNetCore.Annotations/PolyfillCollectionExtensions.cs
+++ b/src/JsonApiDotNetCore.Annotations/PolyfillCollectionExtensions.cs
@@ -1,10 +1,4 @@
-#if NET6_0
using System.Collections.ObjectModel;
-#endif
-
-#if NET6_0
-#pragma warning disable AV1130 // Return type in method signature should be an interface to an unchangeable collection
-#endif
namespace JsonApiDotNetCore;
@@ -13,22 +7,6 @@ internal static class PolyfillCollectionExtensions
{
public static IReadOnlySet AsReadOnly(this HashSet source)
{
- // We can't use ReadOnlySet yet, which is being introduced in .NET 9.
- return source;
- }
-
-#if NET6_0
- public static ReadOnlyDictionary AsReadOnly(this IDictionary source)
- where TKey : notnull
- {
- // The AsReadOnly() extension method is unavailable in .NET 6.
- return new ReadOnlyDictionary(source);
- }
-
- public static ReadOnlyCollection AsReadOnly(this T[] source)
- {
- // The AsReadOnly() extension method is unavailable in .NET 6.
- return Array.AsReadOnly(source);
+ return new ReadOnlySet(source);
}
-#endif
}
diff --git a/src/JsonApiDotNetCore.Annotations/ReadOnlySet.cs b/src/JsonApiDotNetCore.Annotations/ReadOnlySet.cs
new file mode 100644
index 0000000000..1dee77aba9
--- /dev/null
+++ b/src/JsonApiDotNetCore.Annotations/ReadOnlySet.cs
@@ -0,0 +1,169 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#if NET8_0
+#pragma warning disable
+
+// ReadOnlySet was introduced in .NET 9.
+// This file was copied from https://github.com/dotnet/runtime/blob/release/9.0/src/libraries/System.Collections/src/System/Collections/Generic/ReadOnlySet.cs
+// to enable usage on lower .NET versions.
+
+using System.Diagnostics;
+
+namespace System.Collections.ObjectModel;
+
+/// Represents a read-only, generic set of values.
+/// The type of values in the set.
+[DebuggerDisplay("Count = {Count}")]
+public class ReadOnlySet : IReadOnlySet, ISet, ICollection
+{
+ /// The wrapped set.
+ private readonly ISet _set;
+
+ /// Initializes a new instance of the class that is a wrapper around the specified set.
+ /// The set to wrap.
+ public ReadOnlySet(ISet set)
+ {
+ ArgumentNullException.ThrowIfNull(set);
+ _set = set;
+ }
+
+ /// Gets an empty .
+ public static ReadOnlySet Empty { get; } = new ReadOnlySet(new HashSet());
+
+ /// Gets the set that is wrapped by this object.
+ protected ISet Set => _set;
+
+ ///
+ public int Count => _set.Count;
+
+ ///
+ public IEnumerator GetEnumerator() =>
+ _set.Count == 0 ? ((IEnumerable)Array.Empty()).GetEnumerator() :
+ _set.GetEnumerator();
+
+ ///
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ ///
+ public bool Contains(T item) => _set.Contains(item);
+
+ ///
+ public bool IsProperSubsetOf(IEnumerable other) => _set.IsProperSubsetOf(other);
+
+ ///
+ public bool IsProperSupersetOf(IEnumerable other) => _set.IsProperSupersetOf(other);
+
+ ///
+ public bool IsSubsetOf(IEnumerable other) => _set.IsSubsetOf(other);
+
+ ///
+ public bool IsSupersetOf(IEnumerable other) => _set.IsSupersetOf(other);
+
+ ///
+ public bool Overlaps(IEnumerable other) => _set.Overlaps(other);
+
+ ///
+ public bool SetEquals(IEnumerable other) => _set.SetEquals(other);
+
+ ///
+ void ICollection.CopyTo(T[] array, int arrayIndex) => _set.CopyTo(array, arrayIndex);
+
+ ///
+ void ICollection.CopyTo(Array array, int index) => CollectionHelpers.CopyTo(_set, array, index);
+
+ ///
+ bool ICollection.IsReadOnly => true;
+
+ ///
+ bool ICollection.IsSynchronized => false;
+
+ ///
+ object ICollection.SyncRoot => _set is ICollection c ? c.SyncRoot : this;
+
+ ///
+ bool ISet.Add(T item) => throw new NotSupportedException();
+
+ ///
+ void ISet.ExceptWith(IEnumerable other) => throw new NotSupportedException();
+
+ ///
+ void ISet.IntersectWith(IEnumerable other) => throw new NotSupportedException();
+
+ ///
+ void ISet.SymmetricExceptWith(IEnumerable other) => throw new NotSupportedException();
+
+ ///
+ void ISet.UnionWith(IEnumerable other) => throw new NotSupportedException();
+
+ ///
+ void ICollection.Add(T item) => throw new NotSupportedException();
+
+ ///
+ void ICollection.Clear() => throw new NotSupportedException();
+
+ ///
+ bool ICollection.Remove(T item) => throw new NotSupportedException();
+
+ private static class CollectionHelpers
+ {
+ private static void ValidateCopyToArguments(int sourceCount, Array array, int index)
+ {
+ ArgumentNullException.ThrowIfNull(array);
+
+ if (array.Rank != 1)
+ {
+ throw new ArgumentException("Only single dimensional arrays are supported for the requested action.", nameof(array));
+ }
+
+ if (array.GetLowerBound(0) != 0)
+ {
+ throw new ArgumentException("The lower bound of target array must be zero.", nameof(array));
+ }
+
+ ArgumentOutOfRangeException.ThrowIfNegative(index);
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(index, array.Length);
+
+ if (array.Length - index < sourceCount)
+ {
+ throw new ArgumentException("Destination array is not long enough to copy all the items in the collection. Check array index and length.");
+ }
+ }
+
+ internal static void CopyTo(ICollection collection, Array array, int index)
+ {
+ ValidateCopyToArguments(collection.Count, array, index);
+
+ if (collection is ICollection nonGenericCollection)
+ {
+ // Easy out if the ICollection implements the non-generic ICollection
+ nonGenericCollection.CopyTo(array, index);
+ }
+ else if (array is T[] items)
+ {
+ collection.CopyTo(items, index);
+ }
+ else
+ {
+ // We can't cast array of value type to object[], so we don't support widening of primitive types here.
+ if (array is not object?[] objects)
+ {
+ throw new ArgumentException("Target array type is not compatible with the type of items in the collection.", nameof(array));
+ }
+
+ try
+ {
+ foreach (T item in collection)
+ {
+ objects[index++] = item;
+ }
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ throw new ArgumentException("Target array type is not compatible with the type of items in the collection.", nameof(array));
+ }
+ }
+ }
+ }
+}
+#endif
diff --git a/src/JsonApiDotNetCore/Configuration/PageNumber.cs b/src/JsonApiDotNetCore/Configuration/PageNumber.cs
index 44732fc404..f4af725a3d 100644
--- a/src/JsonApiDotNetCore/Configuration/PageNumber.cs
+++ b/src/JsonApiDotNetCore/Configuration/PageNumber.cs
@@ -11,14 +11,7 @@ public sealed class PageNumber : IEquatable
public PageNumber(int oneBasedValue)
{
-#if NET6_0
- if (oneBasedValue < 1)
- {
- throw new ArgumentOutOfRangeException(nameof(oneBasedValue));
- }
-#else
ArgumentOutOfRangeException.ThrowIfLessThan(oneBasedValue, 1);
-#endif
OneBasedValue = oneBasedValue;
}
diff --git a/src/JsonApiDotNetCore/Configuration/PageSize.cs b/src/JsonApiDotNetCore/Configuration/PageSize.cs
index 46beb1419f..4581992597 100644
--- a/src/JsonApiDotNetCore/Configuration/PageSize.cs
+++ b/src/JsonApiDotNetCore/Configuration/PageSize.cs
@@ -9,14 +9,7 @@ public sealed class PageSize : IEquatable
public PageSize(int value)
{
-#if NET6_0
- if (value < 1)
- {
- throw new ArgumentOutOfRangeException(nameof(value));
- }
-#else
ArgumentOutOfRangeException.ThrowIfLessThan(value, 1);
-#endif
Value = value;
}
diff --git a/src/JsonApiDotNetCore/Diagnostics/DefaultCodeTimerSession.cs b/src/JsonApiDotNetCore/Diagnostics/DefaultCodeTimerSession.cs
index 5737dbe3f2..df782bb8c0 100644
--- a/src/JsonApiDotNetCore/Diagnostics/DefaultCodeTimerSession.cs
+++ b/src/JsonApiDotNetCore/Diagnostics/DefaultCodeTimerSession.cs
@@ -27,14 +27,7 @@ public DefaultCodeTimerSession()
private void AssertNotDisposed()
{
-#if NET6_0
- if (_codeTimerInContext.Value == null)
- {
- throw new ObjectDisposedException(nameof(DefaultCodeTimerSession));
- }
-#else
ObjectDisposedException.ThrowIf(_codeTimerInContext.Value == null, this);
-#endif
}
public void Dispose()
diff --git a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj
index 0f395511a7..b30f89cb9f 100644
--- a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj
+++ b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj
@@ -1,6 +1,6 @@
- net8.0;net6.0
+ net8.0
true
true
diff --git a/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs
index 1804027de4..0c704d0013 100644
--- a/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs
+++ b/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs
@@ -135,11 +135,7 @@ public QueryLayer ComposeFromConstraints(ResourceType requestResourceType)
{
ArgumentGuard.NotNull(requestResourceType);
-#if NET6_0
- ImmutableArray constraints = _constraintProviders.SelectMany(provider => provider.GetConstraints()).ToImmutableArray();
-#else
ImmutableArray constraints = [.. _constraintProviders.SelectMany(provider => provider.GetConstraints())];
-#endif
QueryLayer topLayer = ComposeTopLayer(constraints, requestResourceType);
topLayer.Include = ComposeChildren(topLayer, constraints);
diff --git a/test/AnnotationTests/AnnotationTests.csproj b/test/AnnotationTests/AnnotationTests.csproj
index 7c5e5f3ae0..885e9f769c 100644
--- a/test/AnnotationTests/AnnotationTests.csproj
+++ b/test/AnnotationTests/AnnotationTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0;netstandard2.0
+ net9.0;net8.0;netstandard2.0
diff --git a/test/DapperTests/DapperTests.csproj b/test/DapperTests/DapperTests.csproj
index 1420e0dd60..7d41d78911 100644
--- a/test/DapperTests/DapperTests.csproj
+++ b/test/DapperTests/DapperTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/test/DapperTests/IntegrationTests/DapperTestContext.cs b/test/DapperTests/IntegrationTests/DapperTestContext.cs
index 9fdc330c74..01747dde1d 100644
--- a/test/DapperTests/IntegrationTests/DapperTestContext.cs
+++ b/test/DapperTests/IntegrationTests/DapperTestContext.cs
@@ -122,14 +122,10 @@ public async Task ClearAllTablesAsync(DbContext dbContext)
_ => throw new NotSupportedException($"Unsupported database provider '{databaseProvider}'.")
};
-#if !NET6_0
#pragma warning disable EF1002 // Risk of vulnerability to SQL injection.
-#endif
// Justification: Table names cannot be parameterized.
await dbContext.Database.ExecuteSqlRawAsync($"DELETE FROM {escapedTableName}");
-#if !NET6_0
#pragma warning restore EF1002 // Risk of vulnerability to SQL injection.
-#endif
}
}
}
diff --git a/test/DapperTests/IntegrationTests/SqlTextAdapter.cs b/test/DapperTests/IntegrationTests/SqlTextAdapter.cs
index 3bdeab115f..1d6d45555e 100644
--- a/test/DapperTests/IntegrationTests/SqlTextAdapter.cs
+++ b/test/DapperTests/IntegrationTests/SqlTextAdapter.cs
@@ -5,11 +5,7 @@ namespace DapperTests.IntegrationTests;
internal sealed class SqlTextAdapter(DatabaseProvider databaseProvider)
{
-#if NET6_0
- private const RegexOptions Options = RegexOptions.Compiled | RegexOptions.CultureInvariant;
-#else
private const RegexOptions Options = RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.NonBacktracking;
-#endif
private static readonly Dictionary SqlServerReplacements = new()
{
diff --git a/test/DiscoveryTests/DiscoveryTests.csproj b/test/DiscoveryTests/DiscoveryTests.csproj
index 295d5340fa..abeaaa956d 100644
--- a/test/DiscoveryTests/DiscoveryTests.csproj
+++ b/test/DiscoveryTests/DiscoveryTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs
index 93cdf43453..68e7207e4a 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs
@@ -3,9 +3,6 @@
using JsonApiDotNetCore.Serialization.Objects;
using TestBuildingBlocks;
using Xunit;
-#if NET6_0
-using Microsoft.Extensions.DependencyInjection;
-#endif
namespace JsonApiDotNetCoreTests.IntegrationTests.InputValidation.ModelState;
@@ -20,12 +17,6 @@ public ModelStateValidationTests(IntegrationTestContext();
testContext.UseController();
-
-#if NET6_0
- testContext.ConfigureServices(services =>
- // Polyfill for missing DateOnly/TimeOnly support in .NET 6 ModelState validation.
- services.AddDateOnlyTimeOnlyStringConverters());
-#endif
}
[Fact]
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/JsonKebabCaseNamingPolicy.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/JsonKebabCaseNamingPolicy.cs
deleted file mode 100644
index 1d2f948068..0000000000
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/JsonKebabCaseNamingPolicy.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System.Text;
-using System.Text.Json;
-
-namespace JsonApiDotNetCoreTests.IntegrationTests.NamingConventions;
-
-// Based on https://github.com/J0rgeSerran0/JsonNamingPolicy
-internal sealed class JsonKebabCaseNamingPolicy : JsonNamingPolicy
-{
- private const char Separator = '-';
-
- public static readonly JsonKebabCaseNamingPolicy Instance = new();
-
- public override string ConvertName(string name)
- {
- if (string.IsNullOrWhiteSpace(name))
- {
- return string.Empty;
- }
-
- ReadOnlySpan spanName = name.Trim();
-
- var stringBuilder = new StringBuilder();
- bool addCharacter = true;
-
- bool isNextLower = false;
- bool isNextUpper = false;
- bool isNextSpace = false;
-
- for (int position = 0; position < spanName.Length; position++)
- {
- if (position != 0)
- {
- bool isCurrentSpace = spanName[position] == 32;
- bool isPreviousSpace = spanName[position - 1] == 32;
- bool isPreviousSeparator = spanName[position - 1] == 95;
-
- if (position + 1 != spanName.Length)
- {
- isNextLower = spanName[position + 1] is >= 'a' and <= 'z';
- isNextUpper = spanName[position + 1] is >= 'A' and <= 'Z';
- isNextSpace = spanName[position + 1] == ' ';
- }
-
- if (isCurrentSpace && (isPreviousSpace || isPreviousSeparator || isNextUpper || isNextSpace))
- {
- addCharacter = false;
- }
- else
- {
- bool isCurrentUpper = spanName[position] is >= 'A' and <= 'Z';
- bool isPreviousLower = spanName[position - 1] is >= 'a' and <= 'z';
- bool isPreviousNumber = spanName[position - 1] is >= '0' and <= '9';
-
- if (isCurrentUpper && (isPreviousLower || isPreviousNumber || isNextLower || isNextSpace))
- {
- stringBuilder.Append(Separator);
- }
- else
- {
- if (isCurrentSpace)
- {
- stringBuilder.Append(Separator);
- addCharacter = false;
- }
- }
- }
- }
-
- if (addCharacter)
- {
- stringBuilder.Append(spanName[position]);
- }
- else
- {
- addCharacter = true;
- }
- }
-
- return stringBuilder.ToString().ToLowerInvariant();
- }
-}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs
index da3d3b10f9..6321943718 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs
@@ -1,3 +1,4 @@
+using System.Text.Json;
using JetBrains.Annotations;
using JsonApiDotNetCore.Configuration;
using TestBuildingBlocks;
@@ -16,7 +17,7 @@ protected override void SetJsonApiOptions(JsonApiOptions options)
options.UseRelativeLinks = true;
options.IncludeTotalResourceCount = true;
- options.SerializerOptions.PropertyNamingPolicy = JsonKebabCaseNamingPolicy.Instance;
- options.SerializerOptions.DictionaryKeyPolicy = JsonKebabCaseNamingPolicy.Instance;
+ options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.KebabCaseLower;
+ options.SerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.KebabCaseLower;
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/RgbColor.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/RgbColor.cs
index 8eeabbee1d..28762384c9 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/RgbColor.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/RgbColor.cs
@@ -8,11 +8,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ReadWrite;
[Resource(ControllerNamespace = "JsonApiDotNetCoreTests.IntegrationTests.ReadWrite")]
public sealed class RgbColor : Identifiable
{
-#if NET6_0
- // Workaround for bug in .NET 6, see https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/1153.
- public override string? Id { get; set; }
-#endif
-
[Attr]
public string DisplayName { get; set; } = null!;
diff --git a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj
index 95a623d0f9..6bc5a666a1 100644
--- a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj
+++ b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
@@ -13,7 +13,6 @@
-
diff --git a/test/MultiDbContextTests/MultiDbContextTests.csproj b/test/MultiDbContextTests/MultiDbContextTests.csproj
index 6466d8d75f..e80f03c69e 100644
--- a/test/MultiDbContextTests/MultiDbContextTests.csproj
+++ b/test/MultiDbContextTests/MultiDbContextTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj b/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj
index 968d798be3..4deb6b21cd 100644
--- a/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj
+++ b/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/test/SourceGeneratorTests/SourceGeneratorTests.csproj b/test/SourceGeneratorTests/SourceGeneratorTests.csproj
index 8b7d42fdca..4f487fa168 100644
--- a/test/SourceGeneratorTests/SourceGeneratorTests.csproj
+++ b/test/SourceGeneratorTests/SourceGeneratorTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/test/TestBuildingBlocks/CapturingLoggerProvider.cs b/test/TestBuildingBlocks/CapturingLoggerProvider.cs
index 38ec60ed3a..20503c4248 100644
--- a/test/TestBuildingBlocks/CapturingLoggerProvider.cs
+++ b/test/TestBuildingBlocks/CapturingLoggerProvider.cs
@@ -10,10 +10,10 @@ public sealed class CapturingLoggerProvider : ILoggerProvider
private static readonly Func DefaultFilter = (_, _) => true;
private readonly Func _filter;
-#if NET9_0_OR_GREATER
- private readonly Lock _lockObject = new();
-#else
+#if NET8_0
private readonly object _lockObject = new();
+#else
+ private readonly Lock _lockObject = new();
#endif
private readonly List _messages = [];
diff --git a/test/TestBuildingBlocks/DbContextExtensions.cs b/test/TestBuildingBlocks/DbContextExtensions.cs
index 1d1dbc0650..d3a8a0e8ad 100644
--- a/test/TestBuildingBlocks/DbContextExtensions.cs
+++ b/test/TestBuildingBlocks/DbContextExtensions.cs
@@ -44,14 +44,10 @@ private static async Task ClearTablesAsync(this DbContext dbContext, params Type
}
else
{
-#if !NET6_0
#pragma warning disable EF1002 // Risk of vulnerability to SQL injection.
-#endif
// Justification: Table names cannot be parameterized.
await dbContext.Database.ExecuteSqlRawAsync($"DELETE FROM \"{tableName}\"");
-#if !NET6_0
#pragma warning restore EF1002 // Risk of vulnerability to SQL injection.
-#endif
}
}
}
diff --git a/test/TestBuildingBlocks/TestBuildingBlocks.csproj b/test/TestBuildingBlocks/TestBuildingBlocks.csproj
index a6f6ff4299..ddb6edb9dc 100644
--- a/test/TestBuildingBlocks/TestBuildingBlocks.csproj
+++ b/test/TestBuildingBlocks/TestBuildingBlocks.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0
diff --git a/test/UnitTests/UnitTests.csproj b/test/UnitTests/UnitTests.csproj
index e977ac0c8c..68076a51e1 100644
--- a/test/UnitTests/UnitTests.csproj
+++ b/test/UnitTests/UnitTests.csproj
@@ -1,6 +1,6 @@
- net9.0;net8.0;net6.0
+ net9.0;net8.0