diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
index 4f1071c3..30854a39 100644
--- a/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
+++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
@@ -77,6 +77,22 @@ namespace OpenIddict.Abstractions
/// An instance containing the item value.
public OpenIddictParameter? this[string name] => GetNamedParameter(name);
+ ///
+ /// Gets the number of unnamed child items contained in the current parameter or
+ /// 0 if the parameter doesn't represent an array of strings or a JSON array.
+ ///
+ public int Count => Value switch
+ {
+ // If the parameter is a primitive array of strings, return its length.
+ string[] value => value.Length,
+
+ // If the parameter is a JSON array, return its length.
+ JsonElement value when value.ValueKind == JsonValueKind.Array => value.GetArrayLength(),
+
+ // Otherwise, return 0.
+ _ => 0
+ };
+
///
/// Gets the associated value, that can be either a primitive CLR type
/// (e.g bool, string, long), an array of strings or a complex JSON object.
diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs
index d6b0a115..a35e041b 100644
--- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs
+++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs
@@ -9,7 +9,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
-using System.Text.Encodings.Web;
using System.Text.Json;
using Xunit;
@@ -17,6 +16,82 @@ namespace OpenIddict.Abstractions.Tests.Primitives
{
public class OpenIddictParameterTests
{
+ [Fact]
+ public void Count_ReturnsZeroForNullValue()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter();
+
+ // Act and assert
+ Assert.Equal(0, parameter.Count);
+ }
+
+ [Fact]
+ public void Count_ReturnsZeroForBoolean()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter(true);
+
+ // Act and assert
+ Assert.Equal(0, parameter.Count);
+ }
+
+ [Fact]
+ public void Count_ReturnsZeroForInteger()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter(42);
+
+ // Act and assert
+ Assert.Equal(0, parameter.Count);
+ }
+
+ [Fact]
+ public void Count_ReturnsZeroForString()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter("Fabrikam");
+
+ // Act and assert
+ Assert.Equal(0, parameter.Count);
+ }
+
+ [Fact]
+ public void Count_ReturnsExpectedValueForArray()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter(new[]
+ {
+ "Fabrikam",
+ "Contoso"
+ });
+
+ // Act and assert
+ Assert.Equal(2, parameter.Count);
+ }
+
+ [Fact]
+ public void Count_ReturnsExpectedValueForJsonArray()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter(
+ JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]"));
+
+ // Act and assert
+ Assert.Equal(2, parameter.Count);
+ }
+
+ [Fact]
+ public void Count_ReturnsZeroForJsonObjects()
+ {
+ // Arrange
+ var parameter = new OpenIddictParameter(
+ JsonSerializer.Deserialize(@"{""parameter"":""value""}"));
+
+ // Act and assert
+ Assert.Equal(0, parameter.Count);
+ }
+
[Fact]
public void Equals_ReturnsTrueWhenBothParametersAreNull()
{