diff --git a/src/WireMock.Net.Extensions.Routing/WireMock.Net.Extensions.Routing.csproj b/src/WireMock.Net.Extensions.Routing/WireMock.Net.Extensions.Routing.csproj
index 222fffc0..11578493 100644
--- a/src/WireMock.Net.Extensions.Routing/WireMock.Net.Extensions.Routing.csproj
+++ b/src/WireMock.Net.Extensions.Routing/WireMock.Net.Extensions.Routing.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/src/WireMock.Net.Minimal/Serialization/MappingSerializer.cs b/src/WireMock.Net.Minimal/Serialization/MappingSerializer.cs
index 6386dbef..5de20e49 100644
--- a/src/WireMock.Net.Minimal/Serialization/MappingSerializer.cs
+++ b/src/WireMock.Net.Minimal/Serialization/MappingSerializer.cs
@@ -1,6 +1,7 @@
// Copyright © WireMock.Net
using JsonConverter.Abstractions;
+using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER || NET6_0_OR_GREATER || NET461
using System.Text.Json;
@@ -10,9 +11,15 @@ namespace WireMock.Serialization;
internal class MappingSerializer(IJsonConverter jsonConverter)
{
+ private static readonly JsonConverterOptions JsonConverterOptions = new JsonConverterOptions
+ {
+ DateParseHandling = (int) DateParseHandling.None
+ };
+
internal T[] DeserializeJsonToArray(string value)
{
- return DeserializeObjectToArray(jsonConverter.Deserialize
diff --git a/test/WireMock.Net.Tests/Serialization/MappingSerializerTests.cs b/test/WireMock.Net.Tests/Serialization/MappingSerializerTests.cs
index 1cd66b3c..2c74b205 100644
--- a/test/WireMock.Net.Tests/Serialization/MappingSerializerTests.cs
+++ b/test/WireMock.Net.Tests/Serialization/MappingSerializerTests.cs
@@ -3,6 +3,8 @@
using JsonConverter.Newtonsoft.Json;
using WireMock.Admin.Mappings;
using WireMock.Serialization;
+using Newtonsoft.Json.Linq;
+
#if NET8_0_OR_GREATER
using JsonConverter.System.Text.Json;
#endif
@@ -319,5 +321,92 @@ public class MappingSerializerTests
act.Should().Throw()
.WithMessage("Cannot deserialize the provided value to an array or object.");
}
+
+ [Fact]
+ public void MappingSerializer_DeserializeJsonToArray_WithNewtonsoftJson_DateTimeStringInQueryParamExactMatcherPattern_ShouldPreservePatternAsString()
+ {
+ // Arrange
+ var jsonConverter = new NewtonsoftJsonConverter();
+ var serializer = new MappingSerializer(jsonConverter);
+ var mappingJson =
+ """
+ {
+ "Guid": "12345678-1234-1234-1234-aaaaaaaaaaaa",
+ "Request": {
+ "Path": "/api/report",
+ "Methods": ["GET"],
+ "Params": [
+ {
+ "Name": "asOfDate",
+ "Matchers": [
+ {
+ "Name": "ExactMatcher",
+ "Pattern": "2021-11-10T13:39:13.705"
+ }
+ ]
+ }
+ ]
+ },
+ "Response": {
+ "StatusCode": 200
+ }
+ }
+ """;
+
+ // Act
+ var result = serializer.DeserializeJsonToArray(mappingJson);
+
+ // Assert
+ result.Should().HaveCount(1);
+ var matcher = result[0].Request!.Params![0].Matchers![0];
+ matcher.Name.Should().Be("ExactMatcher");
+ matcher.Pattern.Should().BeOfType()
+ .Which.Should().Be("2021-11-10T13:39:13.705",
+ "datetime-format strings in ExactMatcher Pattern fields must survive deserialization as strings, " +
+ "not be auto-converted to DateTime by Newtonsoft.Json's DateParseHandling.DateTime");
+ }
+
+ [Fact]
+ public void MappingSerializer_DeserializeJsonToArray_WithNewtonsoftJson_DateTimeStringInJsonMatcherBodyPattern_ShouldPreservePatternAsString()
+ {
+ // Arrange
+ var jsonConverter = new NewtonsoftJsonConverter();
+ var serializer = new MappingSerializer(jsonConverter);
+ // Pattern is an INLINE JSON object (not a string) - this is how WireMock mapping files store
+ // JsonMatcher patterns when recorded. Newtonsoft with DateParseHandling.DateTime will convert
+ // the datetime value inside the JObject to JTokenType.Date during deserialization.
+ var mappingJson =
+ """
+ {
+ "Guid": "12345678-1234-1234-1234-bbbbbbbbbbbb",
+ "Request": {
+ "Path": "/api/report",
+ "Methods": ["POST"],
+ "Body": {
+ "Matcher": {
+ "Name": "JsonMatcher",
+ "Pattern": {"Date": "2021-09-30T00:00:00Z", "Names": ["Cash"]}
+ }
+ }
+ },
+ "Response": {
+ "StatusCode": 200
+ }
+ }
+ """;
+
+ // Act
+ var result = serializer.DeserializeJsonToArray(mappingJson);
+
+ // Assert - datetime values inside the JObject pattern must remain JTokenType.String.
+ result.Should().HaveCount(1);
+ var matcher = result[0].Request!.Body!.Matcher!;
+ matcher.Name.Should().Be("JsonMatcher");
+ var patternJObject = matcher.Pattern.Should().BeOfType().Subject;
+ patternJObject["Date"]!.Type.Should().Be(JTokenType.String,
+ "datetime-format strings inside an inline JsonMatcher body pattern must retain JTokenType.String " +
+ "after deserialization; if DateParseHandling.DateTime auto-converts them to JTokenType.Date, " +
+ "JToken.DeepEquals will fail against incoming request bodies parsed with DateParseHandling.None");
+ }
#endif
}
\ No newline at end of file