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)