From 037406f7e948868785c45f5517f2852ec8a520fe Mon Sep 17 00:00:00 2001
From: Matthew Steeples
Date: Mon, 31 Mar 2025 23:23:46 +0100
Subject: [PATCH] Use Copy Constructor for JsonSerializerSettings
Fixes #29532
Fixes an issue where JsonSerializerSettings.DateFormatString overwrites DateFormatHandling. See #29532 for details
---
.../src/NewtonsoftJsonOutputFormatter.cs | 40 +------------------
.../test/NewtonsoftJsonOutputFormatterTest.cs | 17 ++++++++
2 files changed, 18 insertions(+), 39 deletions(-)
diff --git a/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs b/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs
index faa290950625..f29031eb46b4 100644
--- a/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs
+++ b/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs
@@ -113,7 +113,7 @@ protected virtual JsonSerializer CreateJsonSerializer()
if (_serializerSettings == null)
{
// Lock the serializer settings once the first serialization has been initiated.
- _serializerSettings = ShallowCopy(SerializerSettings);
+ _serializerSettings = new JsonSerializerSettings(SerializerSettings);
}
return JsonSerializer.Create(_serializerSettings);
@@ -190,44 +190,6 @@ public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext co
}
}
- private static JsonSerializerSettings ShallowCopy(JsonSerializerSettings settings)
- {
- var copiedSettings = new JsonSerializerSettings
- {
- FloatParseHandling = settings.FloatParseHandling,
- FloatFormatHandling = settings.FloatFormatHandling,
- DateParseHandling = settings.DateParseHandling,
- DateTimeZoneHandling = settings.DateTimeZoneHandling,
- DateFormatHandling = settings.DateFormatHandling,
- Formatting = settings.Formatting,
- MaxDepth = settings.MaxDepth,
- DateFormatString = settings.DateFormatString,
- Context = settings.Context,
- Error = settings.Error,
- SerializationBinder = settings.SerializationBinder,
- TraceWriter = settings.TraceWriter,
- Culture = settings.Culture,
- ReferenceResolverProvider = settings.ReferenceResolverProvider,
- EqualityComparer = settings.EqualityComparer,
- ContractResolver = settings.ContractResolver,
- ConstructorHandling = settings.ConstructorHandling,
- TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling,
- MetadataPropertyHandling = settings.MetadataPropertyHandling,
- TypeNameHandling = settings.TypeNameHandling,
- PreserveReferencesHandling = settings.PreserveReferencesHandling,
- Converters = settings.Converters,
- DefaultValueHandling = settings.DefaultValueHandling,
- NullValueHandling = settings.NullValueHandling,
- ObjectCreationHandling = settings.ObjectCreationHandling,
- MissingMemberHandling = settings.MissingMemberHandling,
- ReferenceLoopHandling = settings.ReferenceLoopHandling,
- CheckAdditionalContent = settings.CheckAdditionalContent,
- StringEscapeHandling = settings.StringEscapeHandling,
- };
-
- return copiedSettings;
- }
-
private static partial class Log
{
[LoggerMessage(1, LogLevel.Debug, "Buffering IAsyncEnumerable instance of type '{Type}'.", EventName = "BufferingAsyncEnumerable", SkipEnabledCheck = true)]
diff --git a/src/Mvc/Mvc.NewtonsoftJson/test/NewtonsoftJsonOutputFormatterTest.cs b/src/Mvc/Mvc.NewtonsoftJson/test/NewtonsoftJsonOutputFormatterTest.cs
index ceed0fca2c01..79743b92cd64 100644
--- a/src/Mvc/Mvc.NewtonsoftJson/test/NewtonsoftJsonOutputFormatterTest.cs
+++ b/src/Mvc/Mvc.NewtonsoftJson/test/NewtonsoftJsonOutputFormatterTest.cs
@@ -549,6 +549,23 @@ async IAsyncEnumerable AsyncEnumerableThrows([EnumeratorCancellation] Cance
}
}
+ [Fact]
+ public void JsonSerializerSettingsCopyConstructor_DoesNotOverrideDateFormatHandling()
+ {
+ // Arrange
+ var originalSettings = new JsonSerializerSettings
+ {
+ DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
+ };
+
+ // Act
+ var copiedSettings = new JsonSerializerSettings(originalSettings);
+
+ // Assert
+ Assert.Equal(originalSettings.DateFormatHandling, copiedSettings.DateFormatHandling);
+ Assert.Equal(originalSettings.DateFormatString, copiedSettings.DateFormatString);
+ }
+
private class TestableJsonOutputFormatter : NewtonsoftJsonOutputFormatter
{
public TestableJsonOutputFormatter(JsonSerializerSettings serializerSettings)