Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/WireMock.Net.Minimal/Serialization/MappingSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright © WireMock.Net

using System;
using JsonConverter.Abstractions;
using Newtonsoft.Json.Linq;
#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER || NET6_0_OR_GREATER || NET461
using System.Text.Json;
#endif

namespace WireMock.Serialization;

internal class MappingSerializer(IJsonConverter jsonConverter)
{
internal T[] DeserializeJsonToArray<T>(string value)
{
return DeserializeObjectToArray<T>(jsonConverter.Deserialize<object>(value)!);
}

internal static T[] DeserializeObjectToArray<T>(object value)
{
if (value is JArray jArray)
{
return jArray.ToObject<T[]>()!;
}

if (value is JObject jObject)
{
var singleResult = jObject.ToObject<T>();
return [singleResult!];
}

#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER || NET6_0_OR_GREATER || NET461
if (value is JsonElement jElement)
{
if (jElement.ValueKind == JsonValueKind.Array)
{
return jElement.Deserialize<T[]>()!;
}

if (jElement.ValueKind == JsonValueKind.Object)
{
var singleResult = jElement.Deserialize<T>();
return [singleResult!];
}
}
#endif
throw new InvalidOperationException("Cannot deserialize the provided value to an array or object.");
}
}
42 changes: 13 additions & 29 deletions src/WireMock.Net.Minimal/Server/WireMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public bool ReadStaticMappingAndAddOrUpdate(string path)

if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out var value))
{
var mappingModels = DeserializeJsonToArray<MappingModel>(value);
var mappingModels = _mappingSerializer.DeserializeJsonToArray<MappingModel>(value);
if (mappingModels.Length == 1 && Guid.TryParse(filenameWithoutExtension, out var guidFromFilename))
{
ConvertMappingAndRegisterAsRespondProvider(mappingModels[0], guidFromFilename, path);
Expand Down Expand Up @@ -859,6 +859,18 @@ private static ResponseMessage ToResponseMessage(string text)
};
}

private static T[] DeserializeRequestMessageToArray<T>(IRequestMessage requestMessage)
{
if (requestMessage.BodyData?.DetectedBodyType == BodyType.Json && requestMessage.BodyData.BodyAsJson != null)
{
var bodyAsJson = requestMessage.BodyData.BodyAsJson!;

return MappingSerializer.DeserializeObjectToArray<T>(bodyAsJson);
}

throw new NotSupportedException();
}

private static T DeserializeObject<T>(IRequestMessage requestMessage) where T : new()
{
switch (requestMessage.BodyData?.DetectedBodyType)
Expand All @@ -874,32 +886,4 @@ private static ResponseMessage ToResponseMessage(string text)
throw new NotSupportedException();
}
}

private static T[] DeserializeRequestMessageToArray<T>(IRequestMessage requestMessage)
{
if (requestMessage.BodyData?.DetectedBodyType == BodyType.Json && requestMessage.BodyData.BodyAsJson != null)
{
var bodyAsJson = requestMessage.BodyData.BodyAsJson;

return DeserializeObjectToArray<T>(bodyAsJson);
}

throw new NotSupportedException();
}

private static T[] DeserializeJsonToArray<T>(string value)
{
return DeserializeObjectToArray<T>(JsonUtils.DeserializeObject(value));
}

private static T[] DeserializeObjectToArray<T>(object value)
{
if (value is JArray jArray)
{
return jArray.ToObject<T[]>()!;
}

var singleResult = ((JObject)value).ToObject<T>();
return new[] { singleResult! };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void ReadStaticWireMockOrgMappingAndAddOrUpdate(string path)

if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out var value))
{
var mappings = DeserializeJsonToArray<OrgMapping>(value);
var mappings = _mappingSerializer.DeserializeJsonToArray<OrgMapping>(value);
foreach (var mapping in mappings)
{
if (mappings.Length == 1 && Guid.TryParse(filenameWithoutExtension, out var guidFromFilename))
Expand Down
7 changes: 6 additions & 1 deletion src/WireMock.Net.Minimal/Server/WireMockServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime;
using System.Threading;
using AnyOfTypes;
using JetBrains.Annotations;
using JsonConverter.Newtonsoft.Json;
using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Admin.Mappings;
Expand Down Expand Up @@ -47,6 +49,7 @@ public partial class WireMockServer : IWireMockServer
private readonly MappingBuilder _mappingBuilder;
private readonly IGuidUtils _guidUtils = new GuidUtils();
private readonly IDateTimeUtils _dateTimeUtils = new DateTimeUtils();
private readonly MappingSerializer _mappingSerializer;

/// <inheritdoc />
[PublicAPI]
Expand Down Expand Up @@ -357,6 +360,8 @@ protected WireMockServer(WireMockServerSettings settings)
{
_settings = Guard.NotNull(settings);

_mappingSerializer = new MappingSerializer(settings.MappingJsonSerializer ?? new NewtonsoftJsonConverter());

// Set default values if not provided
_settings.Logger = settings.Logger ?? new WireMockNullLogger();
_settings.FileSystemHandler = settings.FileSystemHandler ?? new LocalFileSystemHandler();
Expand Down Expand Up @@ -639,7 +644,7 @@ public IWireMockServer WithMapping(params MappingModel[] mappings)
[PublicAPI]
public IWireMockServer WithMapping(string mappings)
{
var mappingModels = DeserializeJsonToArray<MappingModel>(mappings);
var mappingModels = _mappingSerializer.DeserializeJsonToArray<MappingModel>(mappings);
foreach (var mappingModel in mappingModels)
{
ConvertMappingAndRegisterAsRespondProvider(mappingModel, mappingModel.Guid ?? Guid.NewGuid());
Expand Down
6 changes: 4 additions & 2 deletions src/WireMock.Net.Minimal/WireMock.Net.Minimal.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="JsonConverter.Abstractions" Version="0.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<!--<PackageReference Include="JsonConverter.Abstractions" Version="0.7.0" />-->
<PackageReference Include="JsonConverter.Newtonsoft.Json" Version="0.7.0" />
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
<PackageReference Include="NSwag.Core" Version="13.16.1" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
Expand Down Expand Up @@ -118,11 +118,13 @@

<!-- https://github.com/wiremock/WireMock.Net/issues/507 -->
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
<PackageReference Include="JsonConverter.System.Text.Json" Version="0.7.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
<PackageReference Include="JsonConverter.System.Text.Json" Version="0.7.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
Expand Down
11 changes: 11 additions & 0 deletions src/WireMock.Net.Shared/Settings/WireMockServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using WireMock.Types;
using System.Globalization;
using WireMock.Models;
using JsonConverter.Abstractions;

#if USE_ASPNETCORE
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -338,4 +339,14 @@ public class WireMockServerSettings
/// </summary>
[PublicAPI]
public HandlebarsSettings? HandlebarsSettings { get; set; }

/// <summary>
/// Gets or sets the JSON converter used for MappingModel serialization.
/// </summary>
/// <remarks>
/// Set this property to customize how objects are serialized to and deserialized from JSON during mapping.
/// If not set, the NewtonsoftJsonConverter will be used.
/// </remarks>
[PublicAPI]
public IJsonConverter? MappingJsonSerializer { get; set; }
}
Loading
Loading