diff --git a/src/WireMock.Net.MimePart/Matchers/MimePartMatcher.cs b/src/WireMock.Net.MimePart/Matchers/MimePartMatcher.cs index 32b2df37..8e9b0033 100644 --- a/src/WireMock.Net.MimePart/Matchers/MimePartMatcher.cs +++ b/src/WireMock.Net.MimePart/Matchers/MimePartMatcher.cs @@ -1,7 +1,8 @@ // Copyright © WireMock.Net -using System; -using System.Collections.Generic; +using JsonConverter.Abstractions; +using JsonConverter.Newtonsoft.Json; +using Newtonsoft.Json; using WireMock.Matchers.Helpers; using WireMock.Models.Mime; using WireMock.Util; @@ -15,6 +16,8 @@ public class MimePartMatcher : IMimePartMatcher { private readonly IList<(string Name, Func func)> _matcherFunctions; + private readonly IJsonConverter _jsonConverter; + /// public string Name => nameof(MimePartMatcher); @@ -41,7 +44,8 @@ public class MimePartMatcher : IMimePartMatcher IStringMatcher? contentTypeMatcher, IStringMatcher? contentDispositionMatcher, IStringMatcher? contentTransferEncodingMatcher, - IMatcher? contentMatcher + IMatcher? contentMatcher, + IJsonConverter? jsonConverter = null ) { MatchBehaviour = matchBehaviour; @@ -49,6 +53,7 @@ public class MimePartMatcher : IMimePartMatcher ContentDispositionMatcher = contentDispositionMatcher; ContentTransferEncodingMatcher = contentTransferEncodingMatcher; ContentMatcher = contentMatcher; + _jsonConverter = jsonConverter ?? new NewtonsoftJsonConverter(); _matcherFunctions = []; if (ContentTypeMatcher != null) @@ -107,7 +112,8 @@ public class MimePartMatcher : IMimePartMatcher ContentType = GetContentTypeAsString(mimePart.ContentType), DeserializeJson = true, ContentEncoding = null, // mimePart.ContentType?.CharsetEncoding.ToString(), - DecompressGZipAndDeflate = true + DecompressGZipAndDeflate = true, + DefaultJsonConverter = _jsonConverter }; var bodyData = BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false).GetAwaiter().GetResult(); diff --git a/src/WireMock.Net.Minimal/Http/HttpResponseMessageHelper.cs b/src/WireMock.Net.Minimal/Http/HttpResponseMessageHelper.cs index 3279bc3b..817faf7d 100644 --- a/src/WireMock.Net.Minimal/Http/HttpResponseMessageHelper.cs +++ b/src/WireMock.Net.Minimal/Http/HttpResponseMessageHelper.cs @@ -1,8 +1,7 @@ // Copyright © WireMock.Net -using System.Linq; using System.Net; -using System.Net.Http; +using JsonConverter.Abstractions; using WireMock.Util; namespace WireMock.Http; @@ -15,7 +14,8 @@ internal static class HttpResponseMessageHelper Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate, - bool deserializeFormUrlEncoded) + bool deserializeFormUrlEncoded, + IJsonConverter jsonConverter) { var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode }; @@ -45,7 +45,8 @@ internal static class HttpResponseMessageHelper DeserializeJson = deserializeJson, ContentEncoding = contentEncodingHeader?.FirstOrDefault(), DecompressGZipAndDeflate = decompressGzipAndDeflate, - DeserializeFormUrlEncoded = deserializeFormUrlEncoded + DeserializeFormUrlEncoded = deserializeFormUrlEncoded, + DefaultJsonConverter = jsonConverter }; responseMessage.BodyData = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false); } diff --git a/src/WireMock.Net.Minimal/Matchers/Request/RequestMessageBodyMatcher.cs b/src/WireMock.Net.Minimal/Matchers/Request/RequestMessageBodyMatcher.cs index 090f07fb..083ac4dd 100644 --- a/src/WireMock.Net.Minimal/Matchers/Request/RequestMessageBodyMatcher.cs +++ b/src/WireMock.Net.Minimal/Matchers/Request/RequestMessageBodyMatcher.cs @@ -1,6 +1,5 @@ // Copyright © WireMock.Net -using System.Linq; using Stef.Validation; using WireMock.Matchers.Helpers; using WireMock.Util; diff --git a/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs b/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs index ace4844c..0db51eb4 100644 --- a/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs +++ b/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs @@ -53,7 +53,8 @@ internal class OwinRequestMapper : IOwinRequestMapper ContentType = request.ContentType, DeserializeJson = !options.DisableJsonBodyParsing.GetValueOrDefault(false), ContentEncoding = contentEncodingHeader?.FirstOrDefault(), - DecompressGZipAndDeflate = !options.DisableRequestBodyDecompressing.GetValueOrDefault(false) + DecompressGZipAndDeflate = !options.DisableRequestBodyDecompressing.GetValueOrDefault(false), + DefaultJsonConverter = options.DefaultJsonSerializer }; body = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false); diff --git a/src/WireMock.Net.Minimal/Proxy/ProxyHelper.cs b/src/WireMock.Net.Minimal/Proxy/ProxyHelper.cs index 3e799182..821f4ee2 100644 --- a/src/WireMock.Net.Minimal/Proxy/ProxyHelper.cs +++ b/src/WireMock.Net.Minimal/Proxy/ProxyHelper.cs @@ -48,7 +48,8 @@ internal class ProxyHelper(WireMockServerSettings settings) originalUri, deserializeJson, decompressGzipAndDeflate, - deserializeFormUrlEncoded + deserializeFormUrlEncoded, + _settings.DefaultJsonSerializer ).ConfigureAwait(false); IMapping? newMapping = null; diff --git a/src/WireMock.Net.Shared/Util/BodyParser.cs b/src/WireMock.Net.Shared/Util/BodyParser.cs index 4cdd459f..18a4ae16 100644 --- a/src/WireMock.Net.Shared/Util/BodyParser.cs +++ b/src/WireMock.Net.Shared/Util/BodyParser.cs @@ -128,11 +128,11 @@ internal static class BodyParser { Guard.NotNull(settings); - var bodyWithContentEncoding = await ReadBytesAsync(settings.Stream, settings.ContentEncoding, settings.DecompressGZipAndDeflate).ConfigureAwait(false); + var (ContentType, Bytes) = await ReadBytesAsync(settings.Stream, settings.ContentEncoding, settings.DecompressGZipAndDeflate).ConfigureAwait(false); var data = new BodyData { - BodyAsBytes = bodyWithContentEncoding.Bytes, - DetectedCompression = bodyWithContentEncoding.ContentType, + BodyAsBytes = Bytes, + DetectedCompression = ContentType, DetectedBodyType = BodyType.Bytes, DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(settings.ContentType) }; @@ -168,17 +168,17 @@ internal static class BodyParser data.DetectedBodyType = BodyType.FormUrlEncoded; } - // If string is not null or empty, try to deserialize the string to a JObject - if (settings.DeserializeJson && JsonUtils.IsJson(data.BodyAsString)) + // If string is not null or empty, try to deserialize the string + if (settings.DeserializeJson && settings.DefaultJsonConverter.IsValidJson(data.BodyAsString)) { try { - data.BodyAsJson = JsonUtils.DeserializeObject(data.BodyAsString); + data.BodyAsJson = settings.DefaultJsonConverter.Deserialize(data.BodyAsString); data.DetectedBodyType = BodyType.Json; } catch { - // JsonConvert failed, just ignore. + // JsonConverter failed, just ignore. } } } @@ -201,7 +201,7 @@ internal static class BodyParser return (null, data); } - public static bool IsProbablyText(byte[] data) + private static bool IsProbablyText(byte[] data) { if (data.Length == 0) { diff --git a/src/WireMock.Net.Shared/Util/BodyParserSettings.cs b/src/WireMock.Net.Shared/Util/BodyParserSettings.cs index 2fdaea0b..3b625fde 100644 --- a/src/WireMock.Net.Shared/Util/BodyParserSettings.cs +++ b/src/WireMock.Net.Shared/Util/BodyParserSettings.cs @@ -1,6 +1,7 @@ // Copyright © WireMock.Net -using System.IO; +using JsonConverter.Abstractions; +using JsonConverter.Newtonsoft.Json; namespace WireMock.Util; @@ -35,4 +36,13 @@ internal class BodyParserSettings /// Try to deserialize the body as FormUrlEncoded. /// public bool DeserializeFormUrlEncoded { get; set; } = true; + + /// + /// Gets or sets the default JSON converter used for deserialization. + /// + /// + /// Set this property to customize how objects are serialized to and deserialized from JSON during mapping. + /// Default is . + /// + public IJsonConverter DefaultJsonConverter { get; set; } = new NewtonsoftJsonConverter(); } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/WireMockServerTests.WithBody.cs b/test/WireMock.Net.Tests/WireMockServerTests.WithBody.cs index 58261333..7bba8581 100644 --- a/test/WireMock.Net.Tests/WireMockServerTests.WithBody.cs +++ b/test/WireMock.Net.Tests/WireMockServerTests.WithBody.cs @@ -7,6 +7,7 @@ using System.Text; using System.Text.Json.Serialization; using JsonConverter.System.Text.Json; using WireMock.Matchers; +using WireMock.Net.Xunit; using WireMock.RequestBuilders; using WireMock.ResponseBuilders; using WireMock.Server; @@ -232,9 +233,13 @@ public partial class WireMockServerTests public async Task WireMockServer_WithBodyAsJson_Using_PostAsync_And_JsonPartialWildcardMatcher_And_SystemTextJson_ShouldMatch() { // Arrange - using var server = WireMockServer.Start(x => x.DefaultJsonSerializer = new SystemTextJsonConverter()); + using var server = WireMockServer.Start(settings => + { + settings.Logger = new TestOutputHelperWireMockLogger(testOutputHelper); + settings.DefaultJsonSerializer = new SystemTextJsonConverter(); + }); - var matcher = new JsonPartialWildcardMatcher(new { id = "^[a-f0-9]{32}-[0-9]$" }, ignoreCase: true, regex: true); + var matcher = new SystemTextJsonPartialWildcardMatcher(new { id = "^[a-f0-9]{32}-[0-9]$" }, ignoreCase: true, regex: true); server.Given(Request.Create() .WithHeader("Content-Type", "application/json*") .UsingPost()