This commit is contained in:
Stef Heyenrath
2026-04-20 19:37:09 +02:00
parent 82277c7804
commit 7d1dcc6fb1
8 changed files with 45 additions and 22 deletions

View File

@@ -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<IMimePartData, MatchResult> func)> _matcherFunctions;
private readonly IJsonConverter _jsonConverter;
/// <inheritdoc />
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();

View File

@@ -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);
}

View File

@@ -1,6 +1,5 @@
// Copyright © WireMock.Net
using System.Linq;
using Stef.Validation;
using WireMock.Matchers.Helpers;
using WireMock.Util;

View File

@@ -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);

View File

@@ -48,7 +48,8 @@ internal class ProxyHelper(WireMockServerSettings settings)
originalUri,
deserializeJson,
decompressGzipAndDeflate,
deserializeFormUrlEncoded
deserializeFormUrlEncoded,
_settings.DefaultJsonSerializer
).ConfigureAwait(false);
IMapping? newMapping = null;

View File

@@ -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<object>(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)
{

View File

@@ -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.
/// </summary>
public bool DeserializeFormUrlEncoded { get; set; } = true;
/// <summary>
/// Gets or sets the default JSON converter used for deserialization.
/// </summary>
/// <remarks>
/// Set this property to customize how objects are serialized to and deserialized from JSON during mapping.
/// Default is <see cref="NewtonsoftJsonConverter"/>.
/// </remarks>
public IJsonConverter DefaultJsonConverter { get; set; } = new NewtonsoftJsonConverter();
}

View File

@@ -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()