diff --git a/src/JWT/Builder/JwtBuilder.cs b/src/JWT/Builder/JwtBuilder.cs
index 36f6c61f4..3d486ec80 100644
--- a/src/JWT/Builder/JwtBuilder.cs
+++ b/src/JWT/Builder/JwtBuilder.cs
@@ -3,6 +3,7 @@
using System.Reflection;
using JWT.Algorithms;
using JWT.Serializers;
+using Newtonsoft.Json;
using static JWT.Internal.EncodingHelper;
namespace JWT.Builder
@@ -276,7 +277,7 @@ public string Encode(Type payloadType, object payload)
EnsureCanEncode();
var dic = payloadType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
- .ToDictionary(prop => prop.Name, prop => prop.GetValue(payload, null));
+ .ToDictionary(info => GetPropName(info, _jsonSerializerFactory), prop => prop.GetValue(payload, null));
foreach (var pair in dic)
{
@@ -286,6 +287,37 @@ public string Encode(Type payloadType, object payload)
return Encode();
}
+ private static string GetPropName(MemberInfo prop, IJsonSerializerFactory jsonSerializerFactory)
+ {
+ var customAttributes = prop.GetCustomAttributes(true);
+ foreach (var attribute in customAttributes)
+ {
+ if (jsonSerializerFactory.Create() is JsonNetSerializer)
+ {
+ if (attribute is JsonPropertyAttribute jsonNetProperty)
+ {
+ return jsonNetProperty.PropertyName;
+ }
+ }
+#if MODERN_DOTNET
+ else if (jsonSerializerFactory.Create() is SystemTextSerializer)
+ {
+ if (attribute is System.Text.Json.Serialization.JsonPropertyNameAttribute systemTextSerializerProperty)
+ {
+ return systemTextSerializerProperty.Name;
+ }
+ }
+#endif
+ else
+ {
+ throw new NotSupportedException(
+ $"{jsonSerializerFactory.Create().GetType().Name} is not supported");
+ }
+ }
+
+ return prop.Name;
+ }
+
///
/// Decodes a token using the supplied dependencies.
///
diff --git a/src/JWT/JWT.csproj b/src/JWT/JWT.csproj
index 7513c1e4a..9038b73e5 100644
--- a/src/JWT/JWT.csproj
+++ b/src/JWT/JWT.csproj
@@ -20,7 +20,7 @@
Alexander Batishchev, John Sheehan, Michael Lehenbauer
jwt;json;authorization
CC0-1.0
- 10.0.1
+ 10.0.2
10.0.0.0
10.0.0.0
JWT
diff --git a/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs b/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs
index dbafb02cf..f67bd0082 100644
--- a/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs
+++ b/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs
@@ -433,5 +433,53 @@ public void Decode_ToDictionary_Without_Serializer_Should_Throw_Exception()
action.Should()
.Throw();
}
+
+ [TestMethod]
+ public void Encode_Decode_ToJsonNetDecoratedType_Should_UseDecoratedName_Bug456()
+ {
+ var token = JwtBuilder.Create()
+ .WithAlgorithm(new NoneAlgorithm())
+ .WithJsonSerializer(new JsonNetSerializer());
+
+ var model = new TestData.TestDataJsonNetDecorated
+ {
+ AccessToken = "abc123",
+ };
+
+ var encoded = token.Encode(model);
+ Assert.IsNotNull(encoded);
+
+ token = JwtBuilder.Create()
+ .WithAlgorithm(new NoneAlgorithm())
+ .WithJsonSerializer(new JsonNetSerializer());
+
+ var payloadDecoded = token.Decode(encoded);
+ Assert.AreEqual(model.AccessToken, payloadDecoded.AccessToken);
+ }
+#if NETSTANDARD2_0 || NET6_0 || NET7_0
+
+ [TestMethod]
+ public void Encode_Decode_ToSystemTextSerializerDecoratedType_Should_UseDecoratedName_Bug456()
+ {
+ var token = JwtBuilder.Create()
+ .WithAlgorithm(new NoneAlgorithm())
+ .WithJsonSerializer(new SystemTextSerializer());
+
+ var model = new TestData.TestDataSystemTextSerializerDecorated
+ {
+ AccessToken = "abc123",
+ };
+
+ var encoded = token.Encode(model);
+ Assert.IsNotNull(encoded);
+
+ token = JwtBuilder.Create()
+ .WithAlgorithm(new NoneAlgorithm())
+ .WithJsonSerializer(new SystemTextSerializer());
+
+ var payloadDecoded = token.Decode(encoded);
+ Assert.AreEqual(model.AccessToken, payloadDecoded.AccessToken);
+ }
+#endif
}
}
diff --git a/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs b/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs
index 79cc821c9..9a77a4aed 100644
--- a/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs
+++ b/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs
@@ -381,7 +381,7 @@ public void Encode_With_Secret_Should_Return_Valid_Token_Using_Json_Net()
.HaveCount(3, "because the token should consist of three parts");
}
-#if NETSTANDARD2_0 || NET6_0
+#if NETSTANDARD2_0 || NET6_0 || NET7_0
[TestMethod]
public void Encode_Test_Bug438()
{
diff --git a/tests/JWT.Tests.Common/Models/TestData.cs b/tests/JWT.Tests.Common/Models/TestData.cs
index 94da079e8..9ffeb270a 100644
--- a/tests/JWT.Tests.Common/Models/TestData.cs
+++ b/tests/JWT.Tests.Common/Models/TestData.cs
@@ -17,6 +17,20 @@ public static class TestData
Age = 33
};
+ public class TestDataJsonNetDecorated
+ {
+ [Newtonsoft.Json.JsonProperty("AT")]
+ public string AccessToken { get; set; }
+ }
+
+#if NETSTANDARD2_0 || NET6_0 || NET7_0
+ public class TestDataSystemTextSerializerDecorated
+ {
+ [System.Text.Json.Serialization.JsonPropertyName("AT")]
+ public string AccessToken { get; set; }
+ }
+#endif
+
public const string Secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
public const string Secret2 = "QWORIJkmQWEDIHbjhOIHAUSDFOYnUGWEYT";