mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-10 03:13:53 +02:00
Add Response.WithBody with IJsonConverter (#790)
* Response_ProvideResponse_WithBody_IJsonConverter_SystemTextJson * Guard.NotNull(converter); * . * 0.1.0 * j
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JsonConverter.Abstractions;
|
||||||
|
|
||||||
namespace WireMock.ResponseBuilders;
|
namespace WireMock.ResponseBuilders;
|
||||||
|
|
||||||
@@ -69,4 +70,23 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
|
|||||||
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk every time the response is created.</param>
|
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk every time the response is created.</param>
|
||||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
IResponseBuilder WithBodyFromFile(string filename, bool cache = true);
|
IResponseBuilder WithBodyFromFile(string filename, bool cache = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBody : Create a string response based on a object (which will be converted to a JSON string using the <see cref="IJsonConverter"/>).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="body">The body.</param>
|
||||||
|
/// <param name="converter">The JsonConverter.</param>
|
||||||
|
/// <param name="options">The IJsonConverterOption [optional].</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithBody(object body, IJsonConverter converter, JsonConverterOptions? options = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBody : Create a string response based on a object (which will be converted to a JSON string using the <see cref="IJsonConverter"/>).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="body">The body.</param>
|
||||||
|
/// <param name="encoding">The body encoding, can be <c>null</c>.</param>
|
||||||
|
/// <param name="converter">The JsonConverter.</param>
|
||||||
|
/// <param name="options">The IJsonConverterOption [optional].</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter converter, JsonConverterOptions? options = null);
|
||||||
}
|
}
|
||||||
173
src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
Normal file
173
src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JsonConverter.Abstractions;
|
||||||
|
using Stef.Validation;
|
||||||
|
using WireMock.Types;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
|
namespace WireMock.ResponseBuilders;
|
||||||
|
|
||||||
|
public partial class Response
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
||||||
|
{
|
||||||
|
Guard.NotNull(bodyFactory, nameof(bodyFactory));
|
||||||
|
|
||||||
|
return WithCallbackInternal(true, req => new ResponseMessage
|
||||||
|
{
|
||||||
|
BodyData = new BodyData
|
||||||
|
{
|
||||||
|
DetectedBodyType = BodyType.String,
|
||||||
|
BodyAsString = bodyFactory(req),
|
||||||
|
Encoding = encoding ?? Encoding.UTF8
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBody(Func<IRequestMessage, Task<string>> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
||||||
|
{
|
||||||
|
Guard.NotNull(bodyFactory, nameof(bodyFactory));
|
||||||
|
|
||||||
|
return WithCallbackInternal(true, async req => new ResponseMessage
|
||||||
|
{
|
||||||
|
BodyData = new BodyData
|
||||||
|
{
|
||||||
|
DetectedBodyType = BodyType.String,
|
||||||
|
BodyAsString = await bodyFactory(req).ConfigureAwait(false),
|
||||||
|
Encoding = encoding ?? Encoding.UTF8
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
||||||
|
{
|
||||||
|
Guard.NotNull(body);
|
||||||
|
|
||||||
|
ResponseMessage.BodyDestination = destination;
|
||||||
|
ResponseMessage.BodyData = new BodyData();
|
||||||
|
|
||||||
|
switch (destination)
|
||||||
|
{
|
||||||
|
case BodyDestinationFormat.String:
|
||||||
|
var enc = encoding ?? Encoding.UTF8;
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
|
||||||
|
ResponseMessage.BodyData.BodyAsString = enc.GetString(body);
|
||||||
|
ResponseMessage.BodyData.Encoding = enc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
||||||
|
ResponseMessage.BodyData.BodyAsBytes = body;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromFile"/>
|
||||||
|
public IResponseBuilder WithBodyFromFile(string filename, bool cache = true)
|
||||||
|
{
|
||||||
|
Guard.NotNull(filename);
|
||||||
|
|
||||||
|
ResponseMessage.BodyData = new BodyData
|
||||||
|
{
|
||||||
|
BodyAsFileIsCached = cache,
|
||||||
|
BodyAsFile = filename
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cache && !UseTransformer)
|
||||||
|
{
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.File;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBody(string body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
||||||
|
{
|
||||||
|
Guard.NotNull(body);
|
||||||
|
|
||||||
|
encoding ??= Encoding.UTF8;
|
||||||
|
|
||||||
|
ResponseMessage.BodyDestination = destination;
|
||||||
|
ResponseMessage.BodyData = new BodyData
|
||||||
|
{
|
||||||
|
Encoding = encoding
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (destination)
|
||||||
|
{
|
||||||
|
case BodyDestinationFormat.Bytes:
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
||||||
|
ResponseMessage.BodyData.BodyAsBytes = encoding.GetBytes(body);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BodyDestinationFormat.Json:
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.Json;
|
||||||
|
ResponseMessage.BodyData.BodyAsJson = JsonUtils.DeserializeObject(body);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
|
||||||
|
ResponseMessage.BodyData.BodyAsString = body;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, Encoding, bool?)"/>
|
||||||
|
public IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null)
|
||||||
|
{
|
||||||
|
Guard.NotNull(body);
|
||||||
|
|
||||||
|
ResponseMessage.BodyDestination = null;
|
||||||
|
ResponseMessage.BodyData = new BodyData
|
||||||
|
{
|
||||||
|
Encoding = encoding,
|
||||||
|
DetectedBodyType = BodyType.Json,
|
||||||
|
BodyAsJson = body,
|
||||||
|
BodyAsJsonIndented = indented
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, bool)"/>
|
||||||
|
public IResponseBuilder WithBodyAsJson(object body, bool indented)
|
||||||
|
{
|
||||||
|
return WithBodyAsJson(body, null, indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBody(object body, IJsonConverter converter, JsonConverterOptions? options = null)
|
||||||
|
{
|
||||||
|
return WithBody(body, null, converter, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter converter, JsonConverterOptions? options = null)
|
||||||
|
{
|
||||||
|
Guard.NotNull(body);
|
||||||
|
Guard.NotNull(converter);
|
||||||
|
|
||||||
|
ResponseMessage.BodyDestination = null;
|
||||||
|
ResponseMessage.BodyData = new BodyData
|
||||||
|
{
|
||||||
|
Encoding = encoding,
|
||||||
|
DetectedBodyType = BodyType.String,
|
||||||
|
BodyAsString = converter.Serialize(body, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -15,7 +14,6 @@ using WireMock.Transformers;
|
|||||||
using WireMock.Transformers.Handlebars;
|
using WireMock.Transformers.Handlebars;
|
||||||
using WireMock.Transformers.Scriban;
|
using WireMock.Transformers.Scriban;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
using WireMock.Util;
|
|
||||||
|
|
||||||
namespace WireMock.ResponseBuilders;
|
namespace WireMock.ResponseBuilders;
|
||||||
|
|
||||||
@@ -196,144 +194,6 @@ public partial class Response : IResponseBuilder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
|
||||||
{
|
|
||||||
Guard.NotNull(bodyFactory, nameof(bodyFactory));
|
|
||||||
|
|
||||||
return WithCallbackInternal(true, req => new ResponseMessage
|
|
||||||
{
|
|
||||||
BodyData = new BodyData
|
|
||||||
{
|
|
||||||
DetectedBodyType = BodyType.String,
|
|
||||||
BodyAsString = bodyFactory(req),
|
|
||||||
Encoding = encoding ?? Encoding.UTF8
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IResponseBuilder WithBody(Func<IRequestMessage, Task<string>> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
|
||||||
{
|
|
||||||
Guard.NotNull(bodyFactory, nameof(bodyFactory));
|
|
||||||
|
|
||||||
return WithCallbackInternal(true, async req => new ResponseMessage
|
|
||||||
{
|
|
||||||
BodyData = new BodyData
|
|
||||||
{
|
|
||||||
DetectedBodyType = BodyType.String,
|
|
||||||
BodyAsString = await bodyFactory(req).ConfigureAwait(false),
|
|
||||||
Encoding = encoding ?? Encoding.UTF8
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
|
||||||
{
|
|
||||||
Guard.NotNull(body);
|
|
||||||
|
|
||||||
ResponseMessage.BodyDestination = destination;
|
|
||||||
ResponseMessage.BodyData = new BodyData();
|
|
||||||
|
|
||||||
switch (destination)
|
|
||||||
{
|
|
||||||
case BodyDestinationFormat.String:
|
|
||||||
var enc = encoding ?? Encoding.UTF8;
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
|
|
||||||
ResponseMessage.BodyData.BodyAsString = enc.GetString(body);
|
|
||||||
ResponseMessage.BodyData.Encoding = enc;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
|
||||||
ResponseMessage.BodyData.BodyAsBytes = body;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromFile"/>
|
|
||||||
public IResponseBuilder WithBodyFromFile(string filename, bool cache = true)
|
|
||||||
{
|
|
||||||
Guard.NotNull(filename);
|
|
||||||
|
|
||||||
ResponseMessage.BodyData = new BodyData
|
|
||||||
{
|
|
||||||
BodyAsFileIsCached = cache,
|
|
||||||
BodyAsFile = filename
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cache && !UseTransformer)
|
|
||||||
{
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.File;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IResponseBuilder WithBody(string body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
|
||||||
{
|
|
||||||
Guard.NotNull(body);
|
|
||||||
|
|
||||||
encoding ??= Encoding.UTF8;
|
|
||||||
|
|
||||||
ResponseMessage.BodyDestination = destination;
|
|
||||||
ResponseMessage.BodyData = new BodyData
|
|
||||||
{
|
|
||||||
Encoding = encoding
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (destination)
|
|
||||||
{
|
|
||||||
case BodyDestinationFormat.Bytes:
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
|
||||||
ResponseMessage.BodyData.BodyAsBytes = encoding.GetBytes(body);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BodyDestinationFormat.Json:
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Json;
|
|
||||||
ResponseMessage.BodyData.BodyAsJson = JsonUtils.DeserializeObject(body);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
|
|
||||||
ResponseMessage.BodyData.BodyAsString = body;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, Encoding, bool?)"/>
|
|
||||||
public IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null)
|
|
||||||
{
|
|
||||||
Guard.NotNull(body);
|
|
||||||
|
|
||||||
ResponseMessage.BodyDestination = null;
|
|
||||||
ResponseMessage.BodyData = new BodyData
|
|
||||||
{
|
|
||||||
Encoding = encoding,
|
|
||||||
DetectedBodyType = BodyType.Json,
|
|
||||||
BodyAsJson = body,
|
|
||||||
BodyAsJsonIndented = indented
|
|
||||||
};
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, bool)"/>
|
|
||||||
public IResponseBuilder WithBodyAsJson(object body, bool indented)
|
|
||||||
{
|
|
||||||
return WithBodyAsJson(body, null, indented);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
|
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
|
||||||
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
|
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" PrivateAssets="All" />
|
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="JsonConverter.Abstractions" Version="0.2.0" />
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
|
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
|
||||||
@@ -157,6 +158,12 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="ResponseBuilders\Response.*.cs">
|
||||||
|
<DependentUpon>Response.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.3.5" />
|
<PackageReference Include="Handlebars.Net.Helpers" Version="2.3.5" />
|
||||||
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.3.5" />
|
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.3.5" />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NFluent;
|
using NFluent;
|
||||||
@@ -12,8 +13,8 @@ using WireMock.Types;
|
|||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.ResponseBuilders
|
namespace WireMock.Net.Tests.ResponseBuilders;
|
||||||
{
|
|
||||||
public class ResponseWithBodyTests
|
public class ResponseWithBodyTests
|
||||||
{
|
{
|
||||||
private const string ClientIp = "::1";
|
private const string ClientIp = "::1";
|
||||||
@@ -324,5 +325,26 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
|||||||
Check.That(response.Message.StatusCode).IsEqualTo(200);
|
Check.That(response.Message.StatusCode).IsEqualTo(200);
|
||||||
Check.That(response.Message.BodyData.BodyAsString).Contains("File deleted.");
|
Check.That(response.Message.BodyData.BodyAsString).Contains("File deleted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !(NET451 || NET452)
|
||||||
|
[Fact]
|
||||||
|
public async Task Response_ProvideResponse_WithBody_IJsonConverter_SystemTextJson()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var requestBody = new BodyData
|
||||||
|
{
|
||||||
|
DetectedBodyType = BodyType.String,
|
||||||
|
BodyAsString = "abc"
|
||||||
|
};
|
||||||
|
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, requestBody);
|
||||||
|
|
||||||
|
var responseBuilder = Response.Create().WithBody(new { foo = "bar", n = 42 }, new JsonConverter.System.Text.Json.SystemTextJsonConverter());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.Message.BodyData!.BodyAsString.Should().Be(@"{""foo"":""bar"",""n"":42}");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
@@ -78,6 +78,7 @@
|
|||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' != 'net452'">
|
<ItemGroup Condition="'$(TargetFramework)' != 'net452'">
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
|
<PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
|
||||||
|
<PackageReference Include="JsonConverter.System.Text.Json" Version="0.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user