Compare commits

...

66 Commits

Author SHA1 Message Date
Stef Heyenrath
5388130009 . 2026-02-16 18:41:58 +01:00
Stef Heyenrath
fa3a33dcc6 BodyType 2026-02-16 09:37:51 +01:00
Stef Heyenrath
f29a281b55 goed 2026-02-16 09:22:42 +01:00
Stef Heyenrath
bc15cfcefd log 2026-02-16 09:06:27 +01:00
Stef Heyenrath
452dd2a529 ... 2026-02-15 18:07:38 +01:00
Stef Heyenrath
64c32b60e8 log 2026-02-15 10:54:48 +01:00
Stef Heyenrath
334675f39c . 2026-02-14 17:28:37 +01:00
Stef Heyenrath
385450a3a8 windows 2026-02-14 14:37:38 +01:00
Stef Heyenrath
be9298a2e2 publish ./test/wiremock-coverage.xml 2026-02-14 14:36:04 +01:00
Stef Heyenrath
60eb3980f6 ci - --project 2026-02-14 14:33:38 +01:00
Stef Heyenrath
a5d2bf2496 --project 2026-02-14 14:25:38 +01:00
Stef Heyenrath
989f3b760e --project 2026-02-14 14:23:20 +01:00
Stef Heyenrath
d82a273801 t2 2026-02-14 14:22:25 +01:00
Stef Heyenrath
78d8d6a3da no tunit 2026-02-14 13:28:46 +01:00
Stef Heyenrath
aab167e79c --project 2026-02-14 13:20:44 +01:00
Stef Heyenrath
71c500deee t unit first 2026-02-14 13:17:03 +01:00
Stef Heyenrath
15393bb2b1 WireMock.Net.TUnitTests / 10 2026-02-14 13:15:00 +01:00
Stef Heyenrath
6980468356 T Unit 2026-02-14 13:06:26 +01:00
Stef Heyenrath
6094fa4c8b ct2 2026-02-14 12:56:25 +01:00
Stef Heyenrath
80aa55b2df ct 2026-02-14 12:47:32 +01:00
Stef Heyenrath
c24f2396ff --- 2026-02-14 12:35:15 +01:00
Stef Heyenrath
b172f700e0 ct 2026-02-14 12:23:19 +01:00
Stef Heyenrath
6cc18e796c xunit v3 2026-02-14 11:41:25 +01:00
Stef Heyenrath
99f42fb255 up 2026-02-14 10:48:33 +01:00
Stef Heyenrath
0a612b17df maxRetries 2026-02-14 09:56:55 +01:00
Stef Heyenrath
67f764e41e usings 2026-02-14 09:37:21 +01:00
Stef Heyenrath
d46bae655b using var httpClient = new HttpClient(); 2026-02-14 09:30:24 +01:00
Stef Heyenrath
425fb05c14 mm 2026-02-14 08:59:23 +01:00
Stef Heyenrath
8b27da95a8 Add WebSockets (#1423)
* Add WebSockets

* Add tests

* fix

* more tests

* Add tests

* ...

* remove IOwin

* -

* tests

* fluent

* ok

* match

* .

* byte[]

* x

* func

* func

* byte

* trans

* ...

* frameworks.........

* jmes

* xxx

* sc
2026-02-14 08:42:40 +01:00
Stef Heyenrath
df85649b67 MappingSerializer (Newtonsoft or SystemText)-Json (#1394)
* MappingSerializer

* json

* .

* 0.8.0

* test

* mm
2026-02-14 08:42:18 +01:00
Stef Heyenrath
dff55e175b HttpContext 2026-02-08 19:19:19 +01:00
Stef Heyenrath
88df9af9df Merge branch 'master' into version-2.x 2026-02-07 10:29:48 +01:00
Stef Heyenrath
f73bd5fc4f 1.25.0 2026-01-25 10:08:32 +01:00
Stef Heyenrath
93ee9454a2 mm 2026-01-24 09:19:12 +01:00
Stef Heyenrath
702e156ddc Fix MimePartMatcher and add more tests (#1389)
* mp

* .

* --return

* Fixed

* --

* ...

* fix

* ...

* .
2026-01-24 09:15:43 +01:00
Stef Heyenrath
ff26f95ded mm 2026-01-18 18:43:18 +01:00
Stef Heyenrath
276f329eed mm 2026-01-05 21:38:14 +01:00
Stef Heyenrath
3b3f3604f7 Merge branch 'master' into version-2.x 2025-12-25 13:57:44 +01:00
Stef Heyenrath
d311813851 Merge branch 'master' into version-2.x 2025-12-24 17:00:27 +01:00
Stef Heyenrath
c8e1c66bf2 Merge branch 'master' into version-2.x 2025-12-24 15:30:29 +01:00
Stef Heyenrath
76d6f92be2 mm 2025-12-24 12:18:53 +01:00
Stef Heyenrath
3f349cca4c WireMock.Net.NUnit 2025-12-21 10:17:13 +01:00
Stef Heyenrath
19b85c7856 Merge branch 'master' into version-2.x 2025-12-21 09:50:31 +01:00
Stef Heyenrath
da912be37e mm 2025-12-20 13:46:11 +01:00
Stef Heyenrath
ca9fceab67 mm 2025-12-20 12:10:45 +01:00
Stef Heyenrath
c662bb7ad5 mm 2025-12-19 17:56:26 +01:00
Stef Heyenrath
7d6fd35716 Merge branch 'master' into version-2.x 2025-12-12 11:19:09 +01:00
Stef Heyenrath
1b0b42d538 Merge branch 'master' into version-2.x 2025-12-08 19:16:51 +01:00
Stef Heyenrath
5f7b50a5b8 mm 2025-12-07 10:52:17 +01:00
Stef Heyenrath
2e37e822a8 Merge branch 'master' into version-2.x 2025-11-17 20:15:20 +01:00
Stef Heyenrath
1bc693512f HashSet 2025-10-22 12:26:39 +02:00
Stef Heyenrath
398dfe3eff mm 2025-10-22 11:01:42 +02:00
Stef Heyenrath
02228e5f8a mm 2025-10-06 17:08:28 +02:00
Stef Heyenrath
27d1a4b494 mm 2025-10-06 09:18:20 +02:00
Stef
3e170778c8 HttpClientBuilder / ssl3 2025-10-05 16:55:22 +02:00
Stef
9fa1f4081e mm 2025-10-05 15:19:18 +02:00
Stef Heyenrath
37e140b342 #endif 2025-09-07 19:51:42 +02:00
Stef Heyenrath
4fd3ee1dfd . 2025-08-31 12:51:33 +02:00
Stef Heyenrath
5b43a4f341 NO ConfigureAwait(false) + cleanup 2025-08-31 12:39:51 +02:00
Stef Heyenrath
0960d7cebd openapi 2025-08-31 12:21:21 +02:00
Stef Heyenrath
b111b019bc cleanup + fix tests for net8 2025-08-31 11:39:03 +02:00
Stef Heyenrath
bb561c94d0 cleanup some #if for NETSTANDARD1_3 2025-08-31 11:07:25 +02:00
Stef Heyenrath
5c221ff4fa 12 2025-08-31 10:03:51 +02:00
Stef Heyenrath
3077e7bee1 Setup .NET 9 2025-08-31 09:43:48 +02:00
Stef Heyenrath
ec54599827 mm + ... 2025-08-31 09:21:08 +02:00
Stef Heyenrath
034766a2d6 Version 2.x 2025-08-30 10:24:07 +02:00
421 changed files with 76163 additions and 3823 deletions

4
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,4 @@
# Copilot Instructions
## Project Guidelines
- All new byte[xx] calls should use using var data = ArrayPool<byte>.Shared.Lease(xx); instead of directly allocating byte arrays

View File

@@ -19,17 +19,22 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
# - name: 'WireMock.Net.TUnitTests'
# run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release
- name: 'WireMock.Net.Tests'
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
- name: 'WireMock.Net.Tests.UsingNuGet'
run: dotnet test './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
- name: 'WireMock.Net.TUnitTests'
run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
- name: 'WireMock.Net.Middleware.Tests'
run: dotnet test './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net8.0
run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release
linux-build-and-run:
name: Run Tests on Linux
@@ -46,20 +51,20 @@ jobs:
with:
dotnet-version: '8.0.x'
- name: 'WireMock.Net.TUnitTests'
run: dotnet test --project './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release
- name: 'WireMock.Net.Tests'
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
- name: 'WireMock.Net.Tests.UsingNuGet'
run: dotnet test './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
- name: 'WireMock.Net.TUnitTests'
run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
run: dotnet test --project './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
- name: 'WireMock.Net.Middleware.Tests'
run: dotnet test './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release --framework net8.0
run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release
- name: Install .NET Aspire workload
run: dotnet workload install aspire
- name: 'WireMock.Net.Aspire.Tests'
run: dotnet test './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release
run: dotnet test --project './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release

2
.gitignore vendored
View File

@@ -254,6 +254,6 @@ paket-files/
./report/coverlet/
/test/WireMock.Net.Tests/coverage.opencover.xml
/test/WireMock.Net.Tests/coverage.netcoreapp3.1.opencover.xml
/test/WireMock.Net.Tests/coverage.net5.0.opencover.xml
/test/WireMock.Net.Tests/coverage.net8.0.opencover.xml
*.received.*

View File

@@ -1,3 +1,7 @@
# 1.25.0 (25 January 2026)
- [#1389](https://github.com/wiremock/WireMock.Net/pull/1389) - Fix MimePartMatcher and add more tests [bug] contributed by [StefH](https://github.com/StefH)
- [#1371](https://github.com/wiremock/WireMock.Net/issues/1371) - MimePartMatcher does not match multipart/form-data request body (possible bug?) [bug]
# 1.24.0 (18 January 2026)
- [#1417](https://github.com/wiremock/WireMock.Net/pull/1417) - Update aspire to 13.1 (examples + code) [feature] contributed by [petrroll](https://github.com/petrroll)
- [#1418](https://github.com/wiremock/WireMock.Net/pull/1418) - Add OTEL tracing support for Wiremock + automatic OTEL for Aspire integration [feature] contributed by [petrroll](https://github.com/petrroll)
@@ -471,7 +475,7 @@
# 1.5.30 (28 June 2023)
- [#959](https://github.com/wiremock/WireMock.Net/pull/959) - Fixed logic for FluentAssertions WithHeader [bug] contributed by [StefH](https://github.com/StefH)
- [#962](https://github.com/wiremock/WireMock.Net/pull/962) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.Console.Net472.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#963](https://github.com/wiremock/WireMock.Net/pull/963) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#963](https://github.com/wiremock/WireMock.Net/pull/963) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.StandAlone.net462 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#958](https://github.com/wiremock/WireMock.Net/issues/958) - [FluentAssertions] Should().HaveReceivedACall().WithHeader() only checks the first header with the matching key. [bug]
# 1.5.29 (22 June 2023)
@@ -583,7 +587,7 @@
- [#828](https://github.com/wiremock/WireMock.Net/pull/828) - Add setting to skip saving the string-response in the logging when using WithBody(Func...) [feature] contributed by [StefH](https://github.com/StefH)
- [#832](https://github.com/wiremock/WireMock.Net/pull/832) - Fixes for WireMock.Net.FluentAssertions (callcount behaviour) [feature] contributed by [StefH](https://github.com/StefH)
- [#834](https://github.com/wiremock/WireMock.Net/pull/834) - Support deleting / resetting a single scenario [feature] contributed by [StefH](https://github.com/StefH)
- [#837](https://github.com/wiremock/WireMock.Net/pull/837) - Bump Microsoft.AspNetCore.Server.Kestrel.Core from 2.1.7 to 2.1.25 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#837](https://github.com/wiremock/WireMock.Net/pull/837) - Bump Microsoft.AspNetCore.Server.Kestrel.Core from 2.1.7 to 2.1.25 in /examples/WireMock.Net.StandAlone.net462 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#838](https://github.com/wiremock/WireMock.Net/pull/838) - Add option to ProxySettings to append guid to mapping file contributed by [StefH](https://github.com/StefH)
- [#826](https://github.com/wiremock/WireMock.Net/issues/826) - Dynamic Body not to be cached when a Func is used to created the body [feature]
@@ -631,14 +635,14 @@
- [#776](https://github.com/wiremock/WireMock.Net/issues/776) - Update Scriban.Signed to support more functions, e.g math.random [feature]
# 1.5.2 (24 July 2022)
- [#769](https://github.com/wiremock/WireMock.Net/pull/769) - Bump Microsoft.AspNetCore.Server.Kestrel.Core from 2.1.3 to 2.1.7 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#769](https://github.com/wiremock/WireMock.Net/pull/769) - Bump Microsoft.AspNetCore.Server.Kestrel.Core from 2.1.3 to 2.1.7 in /examples/WireMock.Net.StandAlone.net462 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#771](https://github.com/wiremock/WireMock.Net/pull/771) - JsonPartialMatcher - support Regex [feature] contributed by [StefH](https://github.com/StefH)
# 1.5.1 (08 July 2022)
- [#762](https://github.com/wiremock/WireMock.Net/pull/762) - Bump Newtonsoft.Json from 11.0.2 to 13.0.1 in /examples/WireMock.Net.WebApplication.NETCore2 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#763](https://github.com/wiremock/WireMock.Net/pull/763) - Bump Newtonsoft.Json from 6.0.1 to 13.0.1 in /examples/WireMock.Net.Client.Net472 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#765](https://github.com/wiremock/WireMock.Net/pull/765) - Update WireMock.Org.Abstractions and WireMock.Org.RestClient [feature] contributed by [StefH](https://github.com/StefH)
- [#766](https://github.com/wiremock/WireMock.Net/pull/766) - Bump Microsoft.AspNetCore.Http from 2.1.1 to 2.1.22 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#766](https://github.com/wiremock/WireMock.Net/pull/766) - Bump Microsoft.AspNetCore.Http from 2.1.1 to 2.1.22 in /examples/WireMock.Net.StandAlone.net462 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#767](https://github.com/wiremock/WireMock.Net/pull/767) - Rename (WireMock.Pact.Models.V2)-Request to PactRequest and -Response to PactResponse [feature] contributed by [StefH](https://github.com/StefH)
- [#764](https://github.com/wiremock/WireMock.Net/issues/764) - Wrong mapping of method GetAdminMappingsAsync from IWireMockOrgApi [bug]
@@ -790,7 +794,7 @@
- [#612](https://github.com/wiremock/WireMock.Net/pull/612) - Don't run SonarCloud tasks for PullRequests [feature] contributed by [StefH](https://github.com/StefH)
# 1.4.13 (26 April 2021)
- [#607](https://github.com/wiremock/WireMock.Net/pull/607) - Bump System.Text.Encodings.Web from 4.5.0 to 4.5.1 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#607](https://github.com/wiremock/WireMock.Net/pull/607) - Bump System.Text.Encodings.Web from 4.5.0 to 4.5.1 in /examples/WireMock.Net.StandAlone.net462 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#609](https://github.com/wiremock/WireMock.Net/pull/609) - Add possibility to use settings to generate MappingModel models with wildcard path parameters. [feature] contributed by [StefH](https://github.com/StefH)
- [#608](https://github.com/wiremock/WireMock.Net/issues/608) - Import from OpenApi generates model with path parameter narrowed in range (example value=42 instead of '*') [feature]
@@ -834,7 +838,7 @@
- [#570](https://github.com/wiremock/WireMock.Net/pull/570) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.StandAlone.NETCoreApp [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#571](https://github.com/wiremock/WireMock.Net/pull/571) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Console.NETCoreApp2 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#572](https://github.com/wiremock/WireMock.Net/pull/572) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Console.NETCoreApp [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#573](https://github.com/wiremock/WireMock.Net/pull/573) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Console.Net461.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#573](https://github.com/wiremock/WireMock.Net/pull/573) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Console.net462.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#574](https://github.com/wiremock/WireMock.Net/pull/574) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Console.Net452.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#575](https://github.com/wiremock/WireMock.Net/pull/575) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.StandAlone.Net452 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
- [#576](https://github.com/wiremock/WireMock.Net/pull/576) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Service [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
@@ -1430,7 +1434,7 @@
- [#72](https://github.com/wiremock/WireMock.Net/issues/72) - Matching WithParam on OData End Points
# 1.0.2.10 (12 December 2017)
- [#70](https://github.com/wiremock/WireMock.Net/issues/70) - Proxy/Intercept pattern is throwing a keep alive header error with net461
- [#70](https://github.com/wiremock/WireMock.Net/issues/70) - Proxy/Intercept pattern is throwing a keep alive header error with net462
# 1.0.2.9 (07 December 2017)
- [#71](https://github.com/wiremock/WireMock.Net/pull/71) - Fixed restricted headers on response contributed by [StefH](https://github.com/StefH)

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.24.0</VersionPrefix>
<VersionPrefix>2.0.0-preview-02</VersionPrefix>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
@@ -13,8 +13,9 @@
<RepositoryUrl>https://github.com/wiremock/WireMock.Net</RepositoryUrl>
<ApplicationIcon>../../resources/WireMock.Net-Logo.ico</ApplicationIcon>
<PackageReadmeFile>PackageReadme.md</PackageReadmeFile>
<LangVersion>12.0</LangVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
@@ -45,23 +46,20 @@
<PropertyGroup>
<NuGetAudit>true</NuGetAudit>
<!--<NuGetAuditLevel>low</NuGetAuditLevel>-->
<NuGetAuditLevel>low</NuGetAuditLevel>
<NuGetAuditMode>all</NuGetAuditMode>
</PropertyGroup>
<ItemGroup>
<!-- CVE-2019-0820 -->
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.103" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.15.0.120848">
<!--<PackageReference Include="SonarAnalyzer.CSharp" Version="10.15.0.120848">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</PackageReference>-->
<!-- <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -1,6 +1,6 @@
rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.24.0
SET version=1.25.0
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%

View File

@@ -1,6 +1,5 @@
# 1.24.0 (18 January 2026)
- #1417 Update aspire to 13.1 (examples + code) [feature]
- #1418 Add OTEL tracing support for Wiremock + automatic OTEL for Aspire integration [feature]
- #1214 OpenTelemetry Support for .NET Aspire [feature]
# 1.25.0 (25 January 2026)
- #1389 Fix MimePartMatcher and add more tests [bug]
- #1371 MimePartMatcher does not match multipart/form-data request body (possible bug?) [bug]
The full release notes can be found here: https://github.com/wiremock/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -58,9 +58,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{1DAE
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure Pipelines", "Azure Pipelines", "{5B64F6CA-BF6B-4F67-BB2A-9C47E441703E}"
ProjectSection(SolutionItems) = preProject
azure-pipelines-ci-linux.yml = azure-pipelines-ci-linux.yml
azure-pipelines-ci.yml = azure-pipelines-ci.yml
azure-pipelines-linux.yml = azure-pipelines-linux.yml
azure-pipelines-nuget.yml = azure-pipelines-nuget.yml
EndProjectSection
EndProject
@@ -68,14 +66,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Org.RestClient", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Org.Abstractions", "src\WireMock.Org.Abstractions\WireMock.Org.Abstractions.csproj", "{3BA5109E-5F30-4CC2-B699-02EC82560AA6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication.NET6", "examples\WireMock.Net.WebApplication.NET6\WireMock.Net.WebApplication.NET6.csproj", "{3F7AA023-6833-4856-A08A-4B5717B592B8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp", "examples\WireMock.Net.Console.Proxy.NETCoreApp\WireMock.Net.Console.Proxy.NETCoreApp.csproj", "{670C7562-C154-442E-A249-7D26849BCD13}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.xUnit", "src\WireMock.Net.xUnit\WireMock.Net.xUnit.csproj", "{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NET6.WithCertificate", "examples\WireMock.Net.Console.NET6.WithCertificate\WireMock.Net.Console.NET6.WithCertificate.csproj", "{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueExample", "examples\WireMockAzureQueueExample\WireMockAzureQueueExample.csproj", "{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Testcontainers", "src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj", "{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}"
@@ -118,8 +112,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.AspNetCore.Middleware", "src\WireMock.Net.AspNetCore.Middleware\WireMock.Net.AspNetCore.Middleware.csproj", "{B6269AAC-170A-4346-8B9A-579DED3D9A13}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TestWebApplication", "test\WireMock.Net.TestWebApplication\WireMock.Net.TestWebApplication.csproj", "{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Middleware.Tests", "test\WireMock.Net.Middleware.Tests\WireMock.Net.Middleware.Tests.csproj", "{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.AwesomeAssertions", "src\WireMock.Net.AwesomeAssertions\WireMock.Net.AwesomeAssertions.csproj", "{7753670F-7C7F-44BF-8BC7-08325588E60C}"
@@ -152,6 +144,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.OpenTelemetry"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.OpenTelemetryDemo", "examples\WireMock.Net.OpenTelemetryDemo\WireMock.Net.OpenTelemetryDemo.csproj", "{9957038D-F9C3-CA5D-E8AE-BE188E512635}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.MimePart", "examples\WireMock.Net.Console.MimePart\WireMock.Net.Console.MimePart.csproj", "{4005E20C-D42B-138A-79BE-B3F5420C563F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.NET8.WithCertificate", "examples\WireMock.Net.Console.NET8.WithCertificate\WireMock.Net.Console.NET8.WithCertificate.csproj", "{2D86546D-8A24-0A55-C962-2071BD299E05}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.WebApplication.IIS", "examples\WireMock.Net.WebApplication.IIS\WireMock.Net.WebApplication.IIS.csproj", "{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.WebSocketExamples", "examples\WireMock.Net.WebSocketExamples\WireMock.Net.WebSocketExamples.csproj", "{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.TestWebApplication", "examples\WireMock.Net.TestWebApplication\WireMock.Net.TestWebApplication.csproj", "{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.TestWebApplication", "test\WireMock.Net.TestWebApplication\WireMock.Net.TestWebApplication.csproj", "{3B05CC76-C3CB-8667-6B65-3129DFB25681}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -330,18 +334,6 @@ Global
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Release|x64.Build.0 = Release|Any CPU
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Release|x86.ActiveCfg = Release|Any CPU
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Release|x86.Build.0 = Release|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|x64.ActiveCfg = Debug|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|x64.Build.0 = Debug|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|x86.ActiveCfg = Debug|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Debug|x86.Build.0 = Debug|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|Any CPU.Build.0 = Release|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|x64.ActiveCfg = Release|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|x64.Build.0 = Release|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|x86.ActiveCfg = Release|Any CPU
{3F7AA023-6833-4856-A08A-4B5717B592B8}.Release|x86.Build.0 = Release|Any CPU
{670C7562-C154-442E-A249-7D26849BCD13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{670C7562-C154-442E-A249-7D26849BCD13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{670C7562-C154-442E-A249-7D26849BCD13}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -366,18 +358,6 @@ Global
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Release|x64.Build.0 = Release|Any CPU
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Release|x86.ActiveCfg = Release|Any CPU
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44}.Release|x86.Build.0 = Release|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|x64.ActiveCfg = Debug|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|x64.Build.0 = Debug|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|x86.ActiveCfg = Debug|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Debug|x86.Build.0 = Debug|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|Any CPU.Build.0 = Release|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|x64.ActiveCfg = Release|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|x64.Build.0 = Release|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|x86.ActiveCfg = Release|Any CPU
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34}.Release|x86.Build.0 = Release|Any CPU
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -606,18 +586,6 @@ Global
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Release|x64.Build.0 = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Release|x86.ActiveCfg = Release|Any CPU
{B6269AAC-170A-4346-8B9A-579DED3D9A13}.Release|x86.Build.0 = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|x64.ActiveCfg = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|x64.Build.0 = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|x86.ActiveCfg = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Debug|x86.Build.0 = Debug|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|Any CPU.Build.0 = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|x64.ActiveCfg = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|x64.Build.0 = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|x86.ActiveCfg = Release|Any CPU
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE}.Release|x86.Build.0 = Release|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -810,6 +778,78 @@ Global
{9957038D-F9C3-CA5D-E8AE-BE188E512635}.Release|x64.Build.0 = Release|Any CPU
{9957038D-F9C3-CA5D-E8AE-BE188E512635}.Release|x86.ActiveCfg = Release|Any CPU
{9957038D-F9C3-CA5D-E8AE-BE188E512635}.Release|x86.Build.0 = Release|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Debug|x64.ActiveCfg = Debug|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Debug|x64.Build.0 = Debug|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Debug|x86.ActiveCfg = Debug|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Debug|x86.Build.0 = Debug|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Release|Any CPU.Build.0 = Release|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Release|x64.ActiveCfg = Release|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Release|x64.Build.0 = Release|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Release|x86.ActiveCfg = Release|Any CPU
{4005E20C-D42B-138A-79BE-B3F5420C563F}.Release|x86.Build.0 = Release|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Debug|x64.ActiveCfg = Debug|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Debug|x64.Build.0 = Debug|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Debug|x86.ActiveCfg = Debug|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Debug|x86.Build.0 = Debug|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Release|Any CPU.Build.0 = Release|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Release|x64.ActiveCfg = Release|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Release|x64.Build.0 = Release|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Release|x86.ActiveCfg = Release|Any CPU
{2D86546D-8A24-0A55-C962-2071BD299E05}.Release|x86.Build.0 = Release|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Debug|x64.Build.0 = Debug|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Debug|x86.Build.0 = Debug|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Release|Any CPU.Build.0 = Release|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Release|x64.ActiveCfg = Release|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Release|x64.Build.0 = Release|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Release|x86.ActiveCfg = Release|Any CPU
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C}.Release|x86.Build.0 = Release|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Debug|x64.ActiveCfg = Debug|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Debug|x64.Build.0 = Debug|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Debug|x86.ActiveCfg = Debug|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Debug|x86.Build.0 = Debug|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Release|Any CPU.Build.0 = Release|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Release|x64.ActiveCfg = Release|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Release|x64.Build.0 = Release|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Release|x86.ActiveCfg = Release|Any CPU
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B}.Release|x86.Build.0 = Release|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Debug|x64.ActiveCfg = Debug|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Debug|x64.Build.0 = Debug|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Debug|x86.ActiveCfg = Debug|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Debug|x86.Build.0 = Debug|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Release|Any CPU.Build.0 = Release|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Release|x64.ActiveCfg = Release|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Release|x64.Build.0 = Release|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Release|x86.ActiveCfg = Release|Any CPU
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652}.Release|x86.Build.0 = Release|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Debug|x64.ActiveCfg = Debug|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Debug|x64.Build.0 = Debug|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Debug|x86.ActiveCfg = Debug|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Debug|x86.Build.0 = Debug|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Release|Any CPU.Build.0 = Release|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Release|x64.ActiveCfg = Release|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Release|x64.Build.0 = Release|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Release|x86.ActiveCfg = Release|Any CPU
{3B05CC76-C3CB-8667-6B65-3129DFB25681}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -831,10 +871,8 @@ Global
{5B64F6CA-BF6B-4F67-BB2A-9C47E441703E} = {7EFB2C5B-1BB2-4AAF-BC9F-216ED80C594D}
{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{3BA5109E-5F30-4CC2-B699-02EC82560AA6} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{3F7AA023-6833-4856-A08A-4B5717B592B8} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{670C7562-C154-442E-A249-7D26849BCD13} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{0DE0954F-8C00-4E8D-B94A-4361FC1CBE44} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{56A38798-C48B-4A4A-B805-071E05C02CE1} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
@@ -854,7 +892,6 @@ Global
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE} = {0BB8B634-407A-4610-A91F-11586990767A}
{E72ADFAB-4B42-439E-B1EE-C06E504B35D2} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{B6269AAC-170A-4346-8B9A-579DED3D9A13} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{6B30AA9F-DA04-4EB5-B03C-45A8EF272ECE} = {0BB8B634-407A-4610-A91F-11586990767A}
{A5FEF4F7-7DA2-4962-89A8-16BA942886E5} = {0BB8B634-407A-4610-A91F-11586990767A}
{7753670F-7C7F-44BF-8BC7-08325588E60C} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{E5B03EEF-822C-4295-952B-4479AD30082B} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
@@ -871,6 +908,12 @@ Global
{2DBBD70D-8051-441F-92BB-FF9B8B4B4982} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{C8F4E6D2-9A3B-4F1C-8D5E-7A2B3C4D5E6F} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{9957038D-F9C3-CA5D-E8AE-BE188E512635} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{4005E20C-D42B-138A-79BE-B3F5420C563F} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{2D86546D-8A24-0A55-C962-2071BD299E05} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{5E6E9FA7-9135-7B82-2CCD-8CA87AC8043C} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{2CE8E3A6-59CC-FE9C-9399-AD54E1FA862B} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{2EA75541-E63A-37B7-DA0A-BEA82ECD7652} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{3B05CC76-C3CB-8667-6B65-3129DFB25681} = {0BB8B634-407A-4610-A91F-11586990767A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}

View File

@@ -47,25 +47,25 @@ jobs:
- task: CmdLine@2
inputs:
script: |
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-xunit.xml"
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-xunit.xml"
displayName: 'WireMock.Net.Tests with Coverage'
- task: CmdLine@2
inputs:
script: |
dotnet-coverage collect "dotnet test ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-tunit.xml"
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-tunit.xml"
displayName: 'WireMock.Net.TUnitTests with Coverage'
- task: CmdLine@2
inputs:
script: |
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-middleware.xml"
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-middleware.xml"
displayName: 'WireMock.Net.Middleware.Tests with Coverage'
- task: CmdLine@2
inputs:
script: |
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-aspire.xml"
dotnet-coverage collect "dotnet test --project ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-aspire.xml"
displayName: 'WireMock.Net.Aspire.Tests with Coverage'
- task: CmdLine@2
@@ -95,7 +95,7 @@ jobs:
- task: PublishBuildArtifacts@1
displayName: Publish coverage files
inputs:
PathtoPublish: './test/WireMock.Net.Tests/coverage.net8.0.opencover.xml'
PathtoPublish: './test/wiremock-coverage.xml'
- job: Windows_Build_Test
@@ -109,33 +109,25 @@ jobs:
packageType: 'sdk'
version: '8.0.x'
- task: DotNetCoreCLI@2
- task: CmdLine@2
displayName: 'WireMock.Net.Tests.UsingNuGet'
inputs:
command: 'test'
projects: './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj'
arguments: '--configuration Release'
script: 'dotnet test ./test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj --configuration Release'
- task: DotNetCoreCLI@2
- task: CmdLine@2
displayName: 'WireMock.Net.Tests with Coverage'
inputs:
command: 'test'
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj'
arguments: '--configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
script: 'dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
- task: DotNetCoreCLI@2
displayName: 'WireMock.Net.TUnitTests with Coverage'
inputs:
command: 'test'
projects: './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj'
arguments: '--configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
# - task: CmdLine@2
# displayName: 'WireMock.Net.TUnitTests with Coverage'
# inputs:
# script: 'dotnet test --project ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
- task: DotNetCoreCLI@2
- task: CmdLine@2
displayName: 'WireMock.Net.Middleware.Tests with Coverage'
inputs:
command: 'test'
projects: './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj'
arguments: '--configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
script: 'dotnet test ./test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj --configuration Debug --framework net8.0 --collect:"XPlat Code Coverage" --logger trx'
- job: Windows_Release_to_MyGet
dependsOn: Windows_Build_Test

View File

@@ -0,0 +1,82 @@
// Copyright © WireMock.Net
using Newtonsoft.Json;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.Console.MimePart;
// Test this CURL:
// curl -X POST http://localhost:9091/multipart -F "plainText=This is some plain text;type=text/plain" -F "jsonData={ `"Key`": `"Value`" };type=application/json" -F "image=@image.png;type=image/png"
//
// curl -X POST http://localhost:9091/multipart2 -F "plainText=This is some plain text;type=text/plain" -F "jsonData={ `"Key`": `"Value`" };type=application/json" -F "image=@image.png;type=image/png"
public static class MainApp
{
public static async Task RunAsync()
{
using var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
StartAdminInterface = true,
ReadStaticMappings = true,
//WatchStaticMappings = true,
//WatchStaticMappingsInSubdirectories = true,
Logger = new WireMockConsoleLogger()
});
System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
var textPlainContentTypeMatcher = new ContentTypeMatcher("text/plain");
var textPlainContentMatcher = new ExactMatcher("This is some plain text");
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
var textJsonContentTypeMatcher = new ContentTypeMatcher("application/json");
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var textJsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
var imagePngContentTypeMatcher = new ContentTypeMatcher("image/png");
var imagePngContentDispositionMatcher = new ExactMatcher("form-data; name=\"image\"; filename=\"image.png\"");
var imagePngContentTransferEncodingMatcher = new ExactMatcher("default");
var imagePngContentMatcher = new ExactObjectMatcher(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"));
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, imagePngContentTypeMatcher, imagePngContentDispositionMatcher, imagePngContentTransferEncodingMatcher, imagePngContentMatcher);
var matchers = new IMatcher[]
{
textPlainMatcher,
textJsonMatcher,
imagePngMatcher
};
server
.Given(Request.Create()
.WithPath("/multipart")
.UsingPost()
.WithMultiPart(matchers)
)
.WithGuid("b9c82182-e469-41da-bcaf-b6e3157fefdb")
.RespondWith(Response.Create()
.WithBody("MultiPart is ok")
);
// server.SaveStaticMappings();
System.Console.WriteLine(JsonConvert.SerializeObject(server.MappingModels, Formatting.Indented));
System.Console.WriteLine("Press any key to stop the server");
System.Console.ReadKey();
server.Stop();
System.Console.WriteLine("Displaying all requests");
var allRequests = server.LogEntries;
System.Console.WriteLine(JsonConvert.SerializeObject(allRequests, Formatting.Indented));
System.Console.WriteLine("Press any key to quit");
System.Console.ReadKey();
}
}

View File

@@ -0,0 +1,23 @@
// Copyright © WireMock.Net
using System.Reflection;
using log4net;
using log4net.Config;
using log4net.Repository;
namespace WireMock.Net.Console.MimePart;
static class Program
{
private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
static async Task Main(params string[] args)
{
Log.Info("Starting WireMock.Net.Console.MimePart...");
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
await MainApp.RunAsync();
}
}

View File

@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Content Include="__admin\mappings\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,79 @@
{
"Guid": "b9c82182-e469-41da-bcaf-b6e3157fefdc",
"UpdatedAt": "2025-12-18T17:21:57.3879723Z",
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/multipart2",
"IgnoreCase": false
}
]
},
"Methods": [
"POST"
],
"Body": {
"MatcherName": "MultiPartMatcher",
"Matchers": [
{
"Name": "MimePartMatcher",
"ContentTypeMatcher": {
"Name": "ContentTypeMatcher",
"Pattern": "text/plain",
"IgnoreCase": false
},
"ContentMatcher": {
"Name": "ExactMatcher",
"Pattern": "This is some plain text",
"IgnoreCase": false
}
},
{
"Name": "MimePartMatcher",
"ContentTypeMatcher": {
"Name": "ContentTypeMatcher",
"Pattern": "application/json",
"IgnoreCase": false
},
"ContentMatcher": {
"Name": "JsonMatcher",
"Pattern": {
"Key": "Value"
},
"IgnoreCase": true,
"Regex": false
}
},
{
"Name": "MimePartMatcher",
"ContentTypeMatcher": {
"Name": "ContentTypeMatcher",
"Pattern": "image/png",
"IgnoreCase": false
},
"ContentDispositionMatcher": {
"Name": "ExactMatcher",
"Pattern": "form-data; name=\"image\"; filename=\"image.png\"",
"IgnoreCase": false
},
"ContentTransferEncodingMatcher": {
"Name": "ExactMatcher",
"Pattern": "default",
"IgnoreCase": false
},
"ContentMatcher": {
"Name": "ExactObjectMatcher",
"Pattern": "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"
}
}
],
"MatchOperator": "Or"
}
},
"Response": {
"BodyDestination": "SameAsSource",
"Body": "MultiPart2 is ok"
}
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
</configSections>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
</configuration>

View File

@@ -339,7 +339,7 @@ namespace WireMock.Net.ConsoleApplication
}
}
System.Console.WriteLine("X = {0} ; default = {1} ; pX = {2:0.00} ; valueX = {3:0.00}", xCount, defaultCount, pX, 1.0 * xCount / tot);
return;
using var httpAndHttpsWithPort = WireMockServer.Start(new WireMockServerSettings
{
HostingScheme = HostingScheme.HttpAndHttps,
@@ -376,9 +376,9 @@ namespace WireMock.Net.ConsoleApplication
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); },
#if USE_ASPNETCORE
//#if USE_ASPNETCORE
AdditionalServiceRegistration = services => { System.Console.WriteLine($"AdditionalServiceRegistration : {services.GetType()}"); },
#endif
//#endif
Logger = new WireMockConsoleLogger(),
HandlebarsRegistrationCallback = (handlebarsContext, fileSystemHandler) =>
@@ -399,7 +399,7 @@ namespace WireMock.Net.ConsoleApplication
//var response = await http.GetAsync($"{_wireMockServer.Url}/pricing");
//var value = await response.Content.ReadAsStringAsync();
#if PROTOBUF
//#if PROTOBUF
var protoBufJsonMatcher = new JsonPartialWildcardMatcher(new { name = "*" });
server
.Given(Request.Create()
@@ -478,9 +478,9 @@ namespace WireMock.Net.ConsoleApplication
.WithTrailingHeader("grpc-status", "0")
.WithTransformer()
);
#endif
//#endif
#if GRAPHQL
//#if GRAPHQL
var customScalars = new Dictionary<string, Type> { { "MyCustomScalar", typeof(int) } };
server
.Given(Request.Create()
@@ -554,41 +554,8 @@ namespace WireMock.Net.ConsoleApplication
}
""")
);
#endif
//#endif
#if MIMEKIT
var textPlainContentTypeMatcher = new ContentTypeMatcher("text/plain");
var textPlainContentMatcher = new ExactMatcher("This is some plain text");
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
var textJsonContentTypeMatcher = new ContentTypeMatcher("text/json");
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var textJsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
var imagePngContentTypeMatcher = new ContentTypeMatcher("image/png");
var imagePngContentDispositionMatcher = new ExactMatcher("attachment; filename=\"image.png\"");
var imagePngContentTransferEncodingMatcher = new ExactMatcher("base64");
var imagePngContentMatcher = new ExactObjectMatcher(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"));
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, imagePngContentTypeMatcher, imagePngContentDispositionMatcher, imagePngContentTransferEncodingMatcher, imagePngContentMatcher);
var matchers = new IMatcher[]
{
textPlainMatcher,
textJsonMatcher,
imagePngMatcher
};
server
.Given(Request.Create()
.WithPath("/multipart")
.UsingPost()
.WithMultiPart(matchers)
)
.WithGuid("b9c82182-e469-41da-bcaf-b6e3157fefdb")
.RespondWith(Response.Create()
.WithBody("MultiPart is ok")
);
#endif
// 400 ms
server
.Given(Request.Create()

View File

@@ -1,34 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<!--<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>-->
</PropertyGroup>
<ItemGroup>
<Content Include="__admin\mappings\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="__admin\mappings\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Remove="__admin\mappings\1.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="__admin\mappings\1.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ApplicationIcon>../../resources/WireMock.Net-Logo.ico</ApplicationIcon>
</PropertyGroup>

View File

@@ -7,16 +7,16 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<!--<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
</ItemGroup>
</ItemGroup>-->
<ItemGroup>
<PackageReference Update="SonarAnalyzer.CSharp" Version="10.12.0.118525" />
</ItemGroup>
<!--<ItemGroup>
<PackageReference Include="WireMock.Net" Version="1.8.11" />
</ItemGroup>-->
<ItemGroup>
<PackageReference Include="WireMock.Net" Version="1.12.0" />
</ItemGroup>
</Project>

View File

@@ -6,6 +6,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="2.3.0" />
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />

View File

@@ -115,10 +115,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="log4net">
<Version>3.0.3</Version>
<Version>3.2.0</Version>
</PackageReference>
<PackageReference Include="WireMock.Net">
<Version>1.8.11</Version>
<Version>1.12.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<!--<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>-->
<StartupObject>WireMock.Net.WebApplication.Program</StartupObject>
<AssemblyName>WireMock.Net.WebApplication</AssemblyName>
@@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View File

@@ -0,0 +1,678 @@
// Copyright © WireMock.Net
using System.Net.WebSockets;
using System.Text;
using WireMock.Logging;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.WebSocketExamples;
public static class Program
{
public static async Task Main(string[] args)
{
Console.WriteLine("WireMock.Net WebSocket Examples");
Console.WriteLine("================================\n");
Console.WriteLine("Choose an example to run:");
Console.WriteLine("1. Echo Server");
Console.WriteLine("2. Custom Message Handler");
Console.WriteLine("3. ...");
Console.WriteLine("4. Scenario/State Machine");
Console.WriteLine("5. WebSocket Proxy");
Console.WriteLine("6. Multiple WebSocket Endpoints");
Console.WriteLine("7. All Examples (runs all endpoints)");
Console.WriteLine("0. Exit\n");
Console.Write("Enter choice: ");
var choice = Console.ReadLine();
switch (choice)
{
case "1":
await RunEchoServerExample();
break;
case "2":
await RunCustomMessageHandlerExample();
break;
case "3":
await RunBroadcastExample();
break;
case "4":
await RunScenarioExample();
break;
case "5":
await RunProxyExample();
break;
case "6":
await RunMultipleEndpointsExample();
break;
case "7":
await RunAllExamples();
break;
case "0":
return;
default:
Console.WriteLine("Invalid choice");
break;
}
}
/// <summary>
/// Example 1: Simple Echo Server
/// Echoes back all messages received from the client
/// </summary>
private static async Task RunEchoServerExample()
{
Console.WriteLine("\n=== Echo Server Example ===");
Console.WriteLine("Starting WebSocket echo server...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger()
});
server
.Given(Request.Create()
.WithPath("/ws/echo")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithEcho()
)
);
Console.WriteLine($"Echo server listening at: {server.Urls[0]}/ws/echo");
Console.WriteLine("\nTest with a WebSocket client:");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/echo");
Console.WriteLine("\nPress any key to test or CTRL+C to exit...");
Console.ReadKey();
// Test the echo server
await TestWebSocketEcho(server.Urls[0]);
Console.WriteLine("\nPress any key to stop server...");
Console.ReadKey();
server.Stop();
}
/// <summary>
/// Example 2: Custom Message Handler
/// Processes messages and sends custom responses
/// </summary>
private static async Task RunCustomMessageHandlerExample()
{
Console.WriteLine("\n=== Custom Message Handler Example ===");
Console.WriteLine("Starting WebSocket server with custom message handler...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger()
});
server
.Given(Request.Create()
.WithPath("/ws/chat")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (message, context) =>
{
if (message.MessageType == WebSocketMessageType.Text)
{
var text = message.Text ?? string.Empty;
// Handle different commands
if (text.StartsWith("/help"))
{
await context.SendAsync("Available commands: /help, /time, /echo <text>, /upper <text>, /reverse <text>");
}
else if (text.StartsWith("/time"))
{
await context.SendAsync($"Server time: {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC");
}
else if (text.StartsWith("/echo "))
{
await context.SendAsync(text.Substring(6));
}
else if (text.StartsWith("/upper "))
{
await context.SendAsync(text.Substring(7).ToUpper());
}
else if (text.StartsWith("/reverse "))
{
var toReverse = text.Substring(9);
var reversed = new string(toReverse.Reverse().ToArray());
await context.SendAsync(reversed);
}
else if (text == "/quit")
{
await context.SendAsync("Goodbye!");
await context.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client requested disconnect");
}
else
{
await context.SendAsync($"Unknown command: {text}. Type /help for available commands.");
}
}
})
)
);
Console.WriteLine($"Chat server listening at: {server.Urls[0]}/ws/chat");
Console.WriteLine("\nTest with:");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/chat");
Console.WriteLine("\nThen try commands: /help, /time, /echo hello, /upper hello, /reverse hello");
Console.WriteLine("\nPress any key to test or CTRL+C to exit...");
Console.ReadKey();
await TestWebSocketChat(server.Urls[0]);
Console.WriteLine("\nPress any key to stop server...");
Console.ReadKey();
server.Stop();
}
/// <summary>
/// Example 3: Broadcast Server
/// Broadcasts messages to all connected clients
/// </summary>
private static async Task RunBroadcastExample()
{
Console.WriteLine("\n=== Broadcast Server Example ===");
Console.WriteLine("Starting WebSocket broadcast server...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger()
});
var broadcastMappingGuid = Guid.NewGuid();
server
.Given(Request.Create()
.WithPath("/ws/broadcast")
.WithWebSocketUpgrade()
)
.WithGuid(broadcastMappingGuid)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithBroadcast()
.WithMessageHandler(async (message, context) =>
{
if (message.MessageType == WebSocketMessageType.Text)
{
var text = message.Text ?? string.Empty;
var timestamp = DateTime.UtcNow.ToString("HH:mm:ss");
var broadcastMessage = $"[{timestamp}] Broadcast: {text}";
// Broadcast to all connected clients
await context.BroadcastTextAsync(broadcastMessage);
Console.WriteLine($"Broadcasted to {server.GetWebSocketConnections(broadcastMappingGuid).Count} clients: {text}");
}
})
)
);
Console.WriteLine($"Broadcast server listening at: {server.Urls[0]}/ws/broadcast");
Console.WriteLine("\nConnect multiple clients:");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/broadcast");
Console.WriteLine("\nMessages sent from any client will be broadcast to all clients");
Console.WriteLine("\nPress any key to stop server...");
Console.ReadKey();
server.Stop();
}
/// <summary>
/// Example 4: Scenario/State Machine
/// Demonstrates state transitions during WebSocket session
/// </summary>
private static async Task RunScenarioExample()
{
Console.WriteLine("\n=== Scenario/State Machine Example ===");
Console.WriteLine("Starting WebSocket server with scenario support...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger()
});
// Initial state: Waiting for players
server
.Given(Request.Create()
.WithPath("/ws/game")
.WithWebSocketUpgrade()
)
.InScenario("GameSession")
.WillSetStateTo("Lobby")
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
await ctx.SendAsync("Welcome to the game lobby! Type 'ready' to start or 'quit' to leave.");
})
)
);
// Lobby state: Waiting for ready
server
.Given(Request.Create()
.WithPath("/ws/game")
.WithWebSocketUpgrade()
)
.InScenario("GameSession")
.WhenStateIs("Lobby")
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
var text = msg.Text?.ToLower() ?? string.Empty;
if (text == "ready")
{
ctx.SetScenarioState("Playing");
await ctx.SendAsync("Game started! Type 'attack' to attack, 'defend' to defend, or 'quit' to exit.");
}
else if (text == "quit")
{
await ctx.SendAsync("You left the lobby. Goodbye!");
await ctx.CloseAsync(WebSocketCloseStatus.NormalClosure, "Player quit");
}
else
{
await ctx.SendAsync("In lobby. Type 'ready' to start or 'quit' to leave.");
}
})
)
);
// Playing state: Game is active
server
.Given(Request.Create()
.WithPath("/ws/game")
.WithWebSocketUpgrade()
)
.InScenario("GameSession")
.WhenStateIs("Playing")
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
var text = msg.Text?.ToLower() ?? string.Empty;
if (text == "attack")
{
await ctx.SendAsync("You attacked! Critical hit! 💥");
}
else if (text == "defend")
{
await ctx.SendAsync("You defended! Shield up! 🛡️");
}
else if (text == "quit")
{
ctx.SetScenarioState("GameOver");
await ctx.SendAsync("Game over! Thanks for playing.");
await ctx.CloseAsync(WebSocketCloseStatus.NormalClosure, "Game ended");
}
else
{
await ctx.SendAsync("Unknown action. Type 'attack', 'defend', or 'quit'.");
}
})
)
);
Console.WriteLine($"Game server listening at: {server.Urls[0]}/ws/game");
Console.WriteLine("\nConnect and follow the game flow:");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/game");
Console.WriteLine("\nGame flow: Lobby -> Type 'ready' -> Playing -> Type 'attack'/'defend' -> Type 'quit'");
Console.WriteLine("\nPress any key to stop server...");
Console.ReadKey();
server.Stop();
}
/// <summary>
/// Example 5: WebSocket Proxy
/// Proxies WebSocket connections to another server
/// </summary>
private static async Task RunProxyExample()
{
Console.WriteLine("\n=== WebSocket Proxy Example ===");
Console.WriteLine("Starting WebSocket proxy server...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger()
});
server
.Given(Request.Create()
.WithPath("/ws/proxy")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocketProxy("ws://echo.websocket.org")
);
Console.WriteLine($"Proxy server listening at: {server.Urls[0]}/ws/proxy");
Console.WriteLine("Proxying to: ws://echo.websocket.org");
Console.WriteLine("\nTest with:");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/proxy");
Console.WriteLine("\nPress any key to stop server...");
Console.ReadKey();
server.Stop();
}
/// <summary>
/// Example 6: Multiple WebSocket Endpoints
/// Demonstrates running multiple WebSocket endpoints simultaneously
/// </summary>
private static async Task RunMultipleEndpointsExample()
{
Console.WriteLine("\n=== Multiple WebSocket Endpoints Example ===");
Console.WriteLine("Starting server with multiple WebSocket endpoints...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger(),
WebSocketSettings = new WebSocketSettings
{
MaxConnections = 100,
KeepAliveIntervalSeconds = 30
}
});
// Endpoint 1: Echo
server
.Given(Request.Create()
.WithPath("/ws/echo")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws.WithEcho())
);
// Endpoint 2: Time service
server
.Given(Request.Create()
.WithPath("/ws/time")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
await ctx.SendAsync($"Server time: {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC");
})
)
);
// Endpoint 4: Protocol-specific
server
.Given(Request.Create()
.WithPath("/ws/protocol")
.WithWebSocketUpgrade("chat", "superchat")
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithAcceptProtocol("chat")
.WithMessageHandler(async (msg, ctx) =>
{
await ctx.SendAsync($"Using protocol: chat. Message: {msg.Text}");
})
)
);
Console.WriteLine("Available WebSocket endpoints:");
Console.WriteLine($" 1. Echo: {server.Urls[0]}/ws/echo");
Console.WriteLine($" 2. Time: {server.Urls[0]}/ws/time");
Console.WriteLine($" 3. JSON: {server.Urls[0]}/ws/json");
Console.WriteLine($" 4. Protocol: {server.Urls[0]}/ws/protocol");
Console.WriteLine("\nTest with wscat:");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/echo");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/time");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/json");
Console.WriteLine(" wscat -c ws://localhost:9091/ws/protocol -s chat");
Console.WriteLine("\nPress any key to stop server...");
Console.ReadKey();
server.Stop();
}
/// <summary>
/// Example 7: Run All Examples
/// Starts a server with all example endpoints
/// </summary>
private static async Task RunAllExamples()
{
Console.WriteLine("\n=== All Examples Running ===");
Console.WriteLine("Starting server with all WebSocket endpoints...\n");
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
Logger = new WireMockConsoleLogger(),
WebSocketSettings = new WebSocketSettings
{
MaxConnections = 200
}
});
SetupAllEndpoints(server);
Console.WriteLine("All WebSocket endpoints are running:");
Console.WriteLine($" Echo: {server.Urls[0]}/ws/echo");
Console.WriteLine($" Chat: {server.Urls[0]}/ws/chat");
Console.WriteLine($" Broadcast: {server.Urls[0]}/ws/broadcast");
Console.WriteLine($" Game: {server.Urls[0]}/ws/game");
Console.WriteLine($" Time: {server.Urls[0]}/ws/time");
Console.WriteLine($" JSON: {server.Urls[0]}/ws/json");
Console.WriteLine("\nServer statistics:");
Console.WriteLine($" Total mappings: {server.Mappings.Count}");
Console.WriteLine("\nPress any key to view connection stats or CTRL+C to exit...");
while (true)
{
Console.ReadKey(true);
var connections = server.GetWebSocketConnections();
Console.WriteLine($"\nActive WebSocket connections: {connections.Count}");
foreach (var conn in connections)
{
Console.WriteLine($" - {conn.ConnectionId}: {conn.RequestMessage.Path} (State: {conn.WebSocket.State})");
}
Console.WriteLine("\nPress any key to refresh or CTRL+C to exit...");
}
}
private static void SetupAllEndpoints(WireMockServer server)
{
// Echo endpoint
server
.Given(Request.Create()
.WithPath("/ws/echo")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws.WithEcho())
);
// Chat endpoint
server
.Given(Request.Create()
.WithPath("/ws/chat")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (message, context) =>
{
if (message.MessageType == WebSocketMessageType.Text)
{
await context.SendAsync($"Echo: {message.Text}");
}
})
)
);
// Broadcast endpoint
var broadcastGuid = Guid.NewGuid();
server
.Given(Request.Create()
.WithPath("/ws/broadcast")
.WithWebSocketUpgrade()
)
.WithGuid(broadcastGuid)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithBroadcast()
.WithMessageHandler(async (message, context) =>
{
if (message.MessageType == WebSocketMessageType.Text)
{
await context.BroadcastTextAsync($"[Broadcast] {message.Text}");
}
})
)
);
// Game scenario endpoint
SetupGameScenario(server);
// Time endpoint
server
.Given(Request.Create()
.WithPath("/ws/time")
.WithWebSocketUpgrade()
)
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
await ctx.SendAsync($"Server time: {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC");
})
)
);
}
private static void SetupGameScenario(WireMockServer server)
{
server
.Given(Request.Create()
.WithPath("/ws/game")
.WithWebSocketUpgrade()
)
.InScenario("GameSession")
.WillSetStateTo("Lobby")
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
await ctx.SendAsync("Welcome! Type 'ready' to start.");
})
)
);
server
.Given(Request.Create()
.WithPath("/ws/game")
.WithWebSocketUpgrade()
)
.InScenario("GameSession")
.WhenStateIs("Lobby")
.RespondWith(Response.Create()
.WithWebSocket(ws => ws
.WithMessageHandler(async (msg, ctx) =>
{
if (msg.Text?.ToLower() == "ready")
{
ctx.SetScenarioState("Playing");
await ctx.SendAsync("Game started!");
}
})
)
);
}
// Helper methods for testing
private static async Task TestWebSocketEcho(string baseUrl)
{
try
{
using var client = new ClientWebSocket();
var uri = new Uri($"{baseUrl.Replace("http://", "ws://")}/ws/echo");
Console.WriteLine($"\nConnecting to {uri}...");
await client.ConnectAsync(uri, CancellationToken.None);
Console.WriteLine("Connected!");
var testMessages = new[] { "Hello", "World", "WebSocket", "Test" };
foreach (var testMessage in testMessages)
{
Console.WriteLine($"\nSending: {testMessage}");
var bytes = Encoding.UTF8.GetBytes(testMessage);
await client.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None);
var buffer = new byte[1024];
var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var received = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine($"Received: {received}");
}
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Test complete", CancellationToken.None);
Console.WriteLine("\nTest completed successfully!");
}
catch (Exception ex)
{
Console.WriteLine($"\nTest failed: {ex.Message}");
}
}
private static async Task TestWebSocketChat(string baseUrl)
{
try
{
using var client = new ClientWebSocket();
var uri = new Uri($"{baseUrl.Replace("http://", "ws://")}/ws/chat");
Console.WriteLine($"\nConnecting to {uri}...");
await client.ConnectAsync(uri, CancellationToken.None);
Console.WriteLine("Connected!");
var commands = new[] { "/help", "/time", "/echo Hello", "/upper test", "/reverse hello" };
foreach (var command in commands)
{
Console.WriteLine($"\nSending: {command}");
var bytes = Encoding.UTF8.GetBytes(command);
await client.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None);
var buffer = new byte[1024];
var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var received = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine($"Received: {received}");
await Task.Delay(500);
}
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Test complete", CancellationToken.None);
Console.WriteLine("\nTest completed successfully!");
}
catch (Exception ex)
{
Console.WriteLine($"\nTest failed: {ex.Message}");
}
}
}

View File

@@ -0,0 +1,156 @@
# WireMock.Net WebSocket Examples
This project demonstrates all the WebSocket capabilities of WireMock.Net.
## Prerequisites
- .NET 8.0 SDK
- Optional: `wscat` for manual testing (`npm install -g wscat`)
## Running the Examples
```bash
cd examples/WireMock.Net.WebSocketExamples
dotnet run
```
## Available Examples
### 1. Echo Server
Simple WebSocket echo server that returns all messages back to the client.
**Test with:**
```bash
wscat -c ws://localhost:9091/ws/echo
```
### 2. Custom Message Handler
Chat server with commands: `/help`, `/time`, `/echo`, `/upper`, `/reverse`, `/quit`
**Test with:**
```bash
wscat -c ws://localhost:9091/ws/chat
> /help
> /time
> /echo Hello World
> /upper test
> /reverse hello
```
### 3. Broadcast Server
Messages sent by any client are broadcast to all connected clients.
**Test with multiple terminals:**
```bash
# Terminal 1
wscat -c ws://localhost:9091/ws/broadcast
# Terminal 2
wscat -c ws://localhost:9091/ws/broadcast
# Terminal 3
wscat -c ws://localhost:9091/ws/broadcast
```
Type messages in any terminal and see them appear in all terminals.
### 4. Scenario/State Machine
Game server with state transitions: Lobby -> Playing -> GameOver
**Test with:**
```bash
wscat -c ws://localhost:9091/ws/game
> ready
> attack
> defend
> quit
```
### 5. WebSocket Proxy
Proxies WebSocket connections to echo.websocket.org
**Test with:**
```bash
wscat -c ws://localhost:9091/ws/proxy
```
### 6. Multiple Endpoints
Runs multiple WebSocket endpoints simultaneously:
- `/ws/echo` - Echo server
- `/ws/time` - Returns server time
- `/ws/json` - Returns JSON responses
- `/ws/protocol` - Protocol-specific endpoint
### 7. All Examples
Runs all endpoints at once with connection statistics.
## Features Demonstrated
-**Echo Server** - Simple message echo
-**Custom Handlers** - Complex message processing
-**Broadcast** - Multi-client communication
-**Scenarios** - State machine patterns
-**Proxy** - Forwarding to real WebSocket servers
-**Protocol Negotiation** - Sec-WebSocket-Protocol support
-**JSON Messaging** - Structured data exchange
-**Connection Management** - Track and manage connections
-**Configuration** - Custom WebSocket settings
## Testing with wscat
Install wscat globally:
```bash
npm install -g wscat
```
Basic usage:
```bash
# Connect to endpoint
wscat -c ws://localhost:9091/ws/echo
# Connect with protocol
wscat -c ws://localhost:9091/ws/protocol -s chat
# Connect with headers
wscat -c ws://localhost:9091/ws/echo -H "X-Custom-Header: value"
```
## Testing with C# Client
The examples include built-in C# WebSocket clients for automated testing.
Select options 1 or 2 and press any key to run the automated tests.
## Configuration
WebSocket settings can be configured:
```csharp
var server = WireMockServer.Start(new WireMockServerSettings
{
Port = 9091,
WebSocketSettings = new WebSocketSettings
{
MaxConnections = 100,
ReceiveBufferSize = 8192,
MaxMessageSize = 1048576,
KeepAliveInterval = TimeSpan.FromSeconds(30),
CloseTimeout = TimeSpan.FromMinutes(10),
EnableCompression = true
}
});
```
## Monitoring
When running "All Examples" (option 7), press any key to view:
- Active connection count
- Connection IDs
- Request paths
- WebSocket states
## Notes
- All examples run on port 9091 by default
- Press CTRL+C to stop the server
- Multiple clients can connect simultaneously
- Connection states are tracked and can be queried

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>WireMock.Net.WebSocketExamples</AssemblyName>
<RootNamespace>WireMock.Net.WebSocketExamples</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,25 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<UserSecretsId>bb7d8355-68c4-4f81-8c2d-6cdd80cd7602</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.14.1" />
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.12.1" />
<PackageReference Include="Azure.Storage.Queues" Version="12.12.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.5" />
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.3" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<UserSecretsId>bb7d8355-68c4-4f81-8c2d-6cdd80cd7602</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.14.1" />
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.12.1" />
<PackageReference Include="Azure.Storage.Queues" Version="12.12.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.5" />
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.3" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>

5
global.json Normal file
View File

@@ -0,0 +1,5 @@
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}

View File

@@ -8,6 +8,12 @@ namespace WireMock.Admin.Mappings;
[FluentBuilder.AutoGenerateBuilder]
public class BodyModel
{
/// <summary>
/// The name of the body matcher.
/// Currently only "MultiPartMatcher" is supported.
/// </summary>
public string? MatcherName { get; set; }
/// <summary>
/// Gets or sets the matcher.
/// </summary>

View File

@@ -32,7 +32,7 @@ public class ResponseModel
public object? BodyAsJson { get; set; }
/// <summary>
/// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
/// Gets or sets a value indicating whether the Json Body String needs to be indented.
/// </summary>
public bool? BodyAsJsonIndented { get; set; }

View File

@@ -1,7 +1,5 @@
// Copyright © WireMock.Net
using System;
namespace WireMock.Admin.Requests;
/// <summary>
@@ -17,12 +15,12 @@ public class LogEntryModel
/// <summary>
/// The request.
/// </summary>
public required LogRequestModel Request { get; init; }
public LogRequestModel? Request { get; init; }
/// <summary>
/// The response.
/// </summary>
public required LogResponseModel Response { get; init; }
public LogResponseModel? Response { get; init; }
/// <summary>
/// The mapping unique identifier.

View File

@@ -1,6 +1,7 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using WireMock.Matchers.Request;
namespace WireMock.Admin.Requests;
@@ -47,5 +48,5 @@ public class LogRequestMatchModel
/// <value>
/// The match details.
/// </value>
public IList<object> MatchDetails { get; set; }
public IList<MatchDetail> MatchDetails { get; set; } = [];
}

View File

@@ -1,7 +1,5 @@
// Copyright © WireMock.Net
using System;
using System.Collections.Generic;
using WireMock.Admin.Mappings;
using WireMock.Types;
@@ -20,7 +18,7 @@ public class LogRequestModel
/// <summary>
/// The DateTime.
/// </summary>
public DateTime DateTime { get; set; }
public required DateTime DateTime { get; set; }
/// <summary>
/// The Path.
@@ -60,7 +58,7 @@ public class LogRequestModel
/// <summary>
/// The HTTP Version.
/// </summary>
public string HttpVersion { get; set; } = null!;
public string? HttpVersion { get; set; }
/// <summary>
/// The Headers.

View File

@@ -1,6 +1,5 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using WireMock.Admin.Mappings;
using WireMock.Types;
@@ -64,12 +63,12 @@ public class LogResponseModel
/// <summary>
/// The detected body type (detection based on body content).
/// </summary>
public BodyType? DetectedBodyType { get; set; }
public string? DetectedBodyType { get; set; }
/// <summary>
/// The detected body type (detection based on Content-Type).
/// </summary>
public BodyType? DetectedBodyTypeFromContentType { get; set; }
public string? DetectedBodyTypeFromContentType { get; set; }
/// <summary>
/// The FaultType.
@@ -80,4 +79,14 @@ public class LogResponseModel
/// Gets or sets the Fault percentage.
/// </summary>
public double? FaultPercentage { get; set; }
/// <summary>
/// The DateTime.
/// </summary>
public required DateTime DateTime { get; set; }
/// <summary>
/// The method.
/// </summary>
public string? Method { get; set; }
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using WireMock.Handlers;
using WireMock.Types;
@@ -123,7 +122,6 @@ public class SettingsModel
/// </summary>
public Dictionary<string, string[]>? ProtoDefinitions { get; set; }
#if NETSTANDARD1_3_OR_GREATER || NET461
/// <summary>
/// Server client certificate mode
/// </summary>
@@ -133,5 +131,9 @@ public class SettingsModel
/// Whether to accept any client certificate
/// </summary>
public bool AcceptAnyClientCertificate { get; set; }
#endif
/// <summary>
/// Gets or sets the WebSocket settings.
/// </summary>
public WebSocketSettingsModel? WebSocketSettings { get; set; }
}

View File

@@ -0,0 +1,40 @@
// Copyright © WireMock.Net
namespace WireMock.Admin.Settings;
/// <summary>
/// WebSocket Settings Model
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class WebSocketSettingsModel
{
/// <summary>
/// Maximum number of concurrent WebSocket connections (default: 100)
/// </summary>
public int MaxConnections { get; set; } = 100;
/// <summary>
/// Default receive buffer size in bytes (default: 4096)
/// </summary>
public int ReceiveBufferSize { get; set; } = 4096;
/// <summary>
/// Default keep-alive interval in seconds (default: 30)
/// </summary>
public int KeepAliveIntervalSeconds { get; set; } = 30;
/// <summary>
/// Maximum message size in bytes (default: 1048576 - 1 MB)
/// </summary>
public int MaxMessageSize { get; set; } = 1048576;
/// <summary>
/// Enable WebSocket compression (default: true)
/// </summary>
public bool EnableCompression { get; set; } = true;
/// <summary>
/// Default close timeout in minutes (default: 10)
/// </summary>
public int CloseTimeoutMinutes { get; set; } = 10;
}

View File

@@ -0,0 +1,39 @@
// Copyright © WireMock.Net
namespace WireMock.Constants;
/// <summary>
/// WebSocket constants
/// </summary>
public static class WebSocketConstants
{
/// <summary>
/// Default receive buffer size for WebSocket messages (4 KB)
/// </summary>
public const int DefaultReceiveBufferSize = 4096;
/// <summary>
/// Default keep-alive interval in seconds
/// </summary>
public const int DefaultKeepAliveIntervalSeconds = 30;
/// <summary>
/// Default close timeout in minutes
/// </summary>
public const int DefaultCloseTimeoutMinutes = 10;
/// <summary>
/// Minimum buffer size for WebSocket operations (1 KB)
/// </summary>
public const int MinimumBufferSize = 1024;
/// <summary>
/// Default maximum message size (1 MB)
/// </summary>
public const int DefaultMaxMessageSize = 1024 * 1024;
/// <summary>
/// Proxy forward buffer size (4 KB)
/// </summary>
public const int ProxyForwardBufferSize = 4096;
}

View File

@@ -1,10 +1,6 @@
// Copyright © WireMock.Net
using System;
using System.Collections.Generic;
#if NETSTANDARD1_3_OR_GREATER || NET461
using System.Security.Cryptography.X509Certificates;
#endif
using WireMock.Types;
using WireMock.Util;
@@ -118,13 +114,11 @@ public interface IRequestMessage
/// </summary>
byte[]? BodyAsBytes { get; }
#if MIMEKIT
/// <summary>
/// The original body as MimeMessage.
/// Convenience getter for Handlebars and WireMockAssertions.
/// </summary>
Models.Mime.IMimeMessageData? BodyAsMimeMessage { get; }
#endif
/// <summary>
/// The detected body type. Convenience getter for Handlebars.
@@ -169,10 +163,8 @@ public interface IRequestMessage
/// <returns>The query parameter value as WireMockList or null when not found.</returns>
WireMockList<string>? GetParameter(string key, bool ignoreCase = false);
#if NETSTANDARD1_3_OR_GREATER || NET461
/// <summary>
/// Gets the connection's client certificate
/// </summary>
X509Certificate2? ClientCertificate { get; }
#endif
}

View File

@@ -1,6 +1,5 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using WireMock.ResponseBuilders;
using WireMock.Types;
using WireMock.Util;
@@ -52,6 +51,16 @@ public interface IResponseMessage
/// </summary>
object? StatusCode { get; set; }
/// <summary>
/// Gets the DateTime.
/// </summary>
DateTime DateTime { get; }
/// <summary>
/// Gets the method.
/// </summary>
string? Method { get; }
/// <summary>
/// Adds the header.
/// </summary>

View File

@@ -38,20 +38,20 @@ public interface ILogEntry
/// <summary>
/// Gets the partial match result.
/// </summary>
IRequestMatchResult PartialMatchResult { get; }
IRequestMatchResult? PartialMatchResult { get; }
/// <summary>
/// Gets the request match result.
/// </summary>
IRequestMatchResult RequestMatchResult { get; }
IRequestMatchResult? RequestMatchResult { get; }
/// <summary>
/// Gets the request message.
/// </summary>
IRequestMessage RequestMessage { get; }
IRequestMessage? RequestMessage { get; }
/// <summary>
/// Gets the response message.
/// </summary>
IResponseMessage ResponseMessage { get; }
IResponseMessage? ResponseMessage { get; }
}

View File

@@ -55,4 +55,11 @@ public interface IRequestMatchResult : IComparable
/// <param name="exception">The exception [Optional].</param>
/// <returns>The score.</returns>
double AddScore(Type matcherType, double score, Exception? exception);
/// <summary>
/// Adds the score.
/// </summary>
/// <param name="matchDetail">The matchDetail.</param>
/// <returns>The score.</returns>
double AddMatchDetail(MatchDetail matchDetail);
}

View File

@@ -12,7 +12,12 @@ public class MatchDetail
/// <summary>
/// Gets or sets the type of the matcher.
/// </summary>
public Type MatcherType { get; set; } = null!;
public required Type MatcherType { get; set; }
/// <summary>
/// Gets or sets the type of the matcher.
/// </summary>
public required string Name { get; set; }
/// <summary>
/// Gets or sets the score between 0.0 and 1.0
@@ -24,4 +29,9 @@ public class MatchDetail
/// [Optional]
/// </summary>
public Exception? Exception { get; set; }
/// <summary>
/// The child MatchResults in case of multiple matchers.
/// </summary>
public MatchDetail[]? MatchDetails { get; set; }
}

View File

@@ -37,7 +37,7 @@ public interface IBodyData
object? BodyAsJson { get; set; }
/// <summary>
/// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
/// Gets or sets a value indicating whether the Json Body String needs to be indented.
/// </summary>
bool? BodyAsJsonIndented { get; set; }

View File

@@ -50,5 +50,20 @@ public enum BodyType
/// <summary>
/// Use Server-Sent Events (string)
/// </summary>
SseString
SseString,
/// <summary>
/// WebSocket message in clear text.
/// </summary>
WebSocketText,
/// <summary>
/// WebSocket message in binary format.
/// </summary>
WebSocketBinary,
/// <summary>
/// WebSocket close message.
/// </summary>
WebSocketClose
}

View File

@@ -2,7 +2,6 @@
namespace WireMock.Types;
#if NETSTANDARD1_3_OR_GREATER || NET461
/// <summary>
/// Describes the client certificate requirements for a HTTPS connection.
/// This enum is the same as https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.server.kestrel.https.clientcertificatemode
@@ -29,5 +28,4 @@ public enum ClientCertificateMode
/// It may be requested by the application later.
/// </summary>
DelayCertificate,
}
#endif
}

View File

@@ -1,7 +1,5 @@
// Copyright © WireMock.Net
using System;
namespace WireMock.Types;
[Flags]
@@ -13,5 +11,11 @@ public enum HostingScheme
Https = 0x2,
HttpAndHttps = Http | Https
HttpAndHttps = Http | Https,
Ws = 0x4,
Wss = 0x8,
WsAndWss = Ws | Wss
}

View File

@@ -4,7 +4,7 @@
<Description>Commonly used interfaces, models, enumerations and types.</Description>
<AssemblyTitle>WireMock.Net.Abstractions</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net45;net451;net461;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591;8603</NoWarn>
<AssemblyName>WireMock.Net.Abstractions</AssemblyName>
@@ -33,32 +33,31 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'">
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
</PropertyGroup>
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'net48' ">
--><!-- CVE-2018-8292 / https://github.com/advisories/GHSA-7jgj-8wvc-jh57 --><!--
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>-->
<ItemGroup>
<!-- CVE-2018-8292 / https://github.com/advisories/GHSA-7jgj-8wvc-jh57 -->
<PackageReference Include="System.Net.Http " Version="4.3.4" />
<!-- See also https://mstack.nl/blog/20210801-source-generators -->
<PackageReference Include="FluentBuilder" Version="0.10.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PolySharp" Version="1.15.0">
<PackageReference Include="FluentBuilder" Version="0.13.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('netstandard')) and '$(TargetFramework)' != 'netstandard1.0'">
<PackageReference Include="System.Security.Cryptography.X509Certificates" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'net45' or '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net461'">
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
<PackageReference Include="Required" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="IsExternalInit" Version="1.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -38,7 +38,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
// ReSharper disable once CheckNamespace
namespace WireMock.AwesomeAssertions;

View File

@@ -1,7 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
using WireMock.Constants;
// ReSharper disable once CheckNamespace

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using AnyOfTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
// ReSharper disable once CheckNamespace
namespace WireMock.AwesomeAssertions;

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using WireMock.Matchers;
using WireMock.Server;

View File

@@ -3,21 +3,20 @@
using WireMock.Server;
// ReSharper disable once CheckNamespace
namespace WireMock.AwesomeAssertions
namespace WireMock.AwesomeAssertions;
/// <summary>
/// Contains extension methods for custom assertions in unit tests.
/// </summary>
public static class WireMockExtensions
{
/// <summary>
/// Contains extension methods for custom assertions in unit tests.
/// Returns a <see cref="WireMockReceivedAssertions"/> object that can be used to assert the current <see cref="IWireMockServer"/>.
/// </summary>
public static class WireMockExtensions
/// <param name="instance">The WireMockServer</param>
/// <returns><see cref="WireMockReceivedAssertions"/></returns>
public static WireMockReceivedAssertions Should(this IWireMockServer instance)
{
/// <summary>
/// Returns a <see cref="WireMockReceivedAssertions"/> object that can be used to assert the current <see cref="IWireMockServer"/>.
/// </summary>
/// <param name="instance">The WireMockServer</param>
/// <returns><see cref="WireMockReceivedAssertions"/></returns>
public static WireMockReceivedAssertions Should(this IWireMockServer instance)
{
return new WireMockReceivedAssertions(instance, AssertionChain.GetOrCreate());
}
return new WireMockReceivedAssertions(instance, AssertionChain.GetOrCreate());
}
}

View File

@@ -4,7 +4,7 @@
<Description>AwesomeAssertions extensions for WireMock.Net</Description>
<AssemblyTitle>WireMock.Net.AwesomeAssertions</AssemblyTitle>
<Authors>Francesco Venturoli;Mahmoud Ali;Stef Heyenrath</Authors>
<TargetFrameworks>net47;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.AwesomeAssertions</AssemblyName>
<PackageId>WireMock.Net.AwesomeAssertions</PackageId>
@@ -32,7 +32,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AwesomeAssertions" Version="9.0.0" />
<PackageReference Include="AwesomeAssertions" Version="9.1.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -21,4 +21,4 @@ public sealed class WireMockRequestInfo<TBody> : WireMockRequestInfo
/// Gets or initializes the deserialized request body.
/// </summary>
public TBody? Body { get; init; }
}
}

View File

@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>WireMock.Net.Routing extends WireMock.Net with modern, minimal-API-style routing for .NET</Description>
<Authors>Gennadii Saltyshchak</Authors>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>tdd;mock;http;wiremock;test;server;unittest;routing;minimalapi</PackageTags>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
@@ -25,10 +25,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JsonConverter.Newtonsoft.Json" Version="0.7.0" />
<PackageReference Include="JsonConverter.Abstractions" Version="0.8.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;

View File

@@ -1,7 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
using WireMock.Constants;
// ReSharper disable once CheckNamespace

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using AnyOfTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;

View File

@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using WireMock.Matchers;
using WireMock.Server;

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>FluentAssertions extensions for WireMock.Net</Description>
<AssemblyTitle>WireMock.Net.FluentAssertions</AssemblyTitle>
<Authors>Mahmoud Ali;Stef Heyenrath</Authors>
<TargetFrameworks>net451;net47;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.FluentAssertions</AssemblyName>
<PackageId>WireMock.Net.FluentAssertions</PackageId>
@@ -31,12 +31,8 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="FluentAssertions" Version="5.10.3" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'netstandard1.3'">
<PackageReference Include="FluentAssertions" Version="6.5.1" />
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="7.2.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -140,7 +140,7 @@ public class GraphQLMatcher : IGraphQLMatcher
}
}
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
/// <inheritdoc />

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>GraphQL support for WireMock.Net</Description>
<AssemblyTitle>WireMock.Net.Matchers.GraphQL</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;netstandard2.1;net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>wiremock;matchers;matcher;graphql</PackageTags>
<RootNamespace>WireMock</RootNamespace>
@@ -26,22 +26,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GraphQL.NewtonsoftJson" Version="8.2.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="GraphQL.NewtonsoftJson" Version="8.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.Shared\WireMock.Net.Shared.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -1,7 +1,5 @@
// Copyright © WireMock.Net
using System;
using System.Linq;
using System.Reflection;
using System.Text;
using AnyOfTypes;
@@ -97,7 +95,7 @@ public class CSharpCodeMatcher : ICSharpCodeMatcher
}
}
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
private bool IsMatch(dynamic input, string pattern)
@@ -106,74 +104,6 @@ public class CSharpCodeMatcher : ICSharpCodeMatcher
var inputValue = isMatchWithString ? input : JObject.FromObject(input);
var source = GetSourceForIsMatchWithString(pattern, isMatchWithString);
object? result;
#if (NET451 || NET452)
var compilerParams = new System.CodeDom.Compiler.CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = false,
ReferencedAssemblies =
{
"System.dll",
"System.Core.dll",
"Microsoft.CSharp.dll",
"Newtonsoft.Json.dll"
}
};
using (var codeProvider = new Microsoft.CSharp.CSharpCodeProvider())
{
var compilerResults = codeProvider.CompileAssemblyFromSource(compilerParams, source);
if (compilerResults.Errors.Count != 0)
{
var errors = from System.CodeDom.Compiler.CompilerError er in compilerResults.Errors select er.ToString();
throw new WireMockException(string.Join(", ", errors));
}
var helper = compilerResults.CompiledAssembly?.CreateInstance("CodeHelper");
if (helper == null)
{
throw new WireMockException("CSharpCodeMatcher: Unable to create instance from WireMock.CodeHelper");
}
var methodInfo = helper.GetType().GetMethod("IsMatch");
if (methodInfo == null)
{
throw new WireMockException("CSharpCodeMatcher: Unable to find method 'IsMatch' in WireMock.CodeHelper");
}
try
{
result = methodInfo.Invoke(helper, new[] { inputValue });
}
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper", ex);
}
}
#elif (NET46 || NET461)
dynamic script;
try
{
script = CSScriptLibrary.CSScript.Evaluator.CompileCode(source).CreateObject("*");
}
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Unable to create compiler for WireMock.CodeHelper", ex);
}
try
{
result = script.IsMatch(inputValue);
}
catch (Exception ex)
{
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
}
#elif (NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0_OR_GREATER)
Assembly assembly;
try
{
@@ -194,6 +124,7 @@ public class CSharpCodeMatcher : ICSharpCodeMatcher
throw new WireMockException("CSharpCodeMatcher: Unable to create object from assembly", ex);
}
object? result;
try
{
result = script.IsMatch(inputValue);
@@ -202,9 +133,7 @@ public class CSharpCodeMatcher : ICSharpCodeMatcher
{
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
}
#else
throw new NotSupportedException("The 'CSharpCodeMatcher' cannot be used in netstandard 1.3");
#endif
try
{
return (bool)result;

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>A CSharpCodeMatcher which can be used to match WireMock.Net Requests using C# code.</Description>
<AssemblyTitle>WireMock.Net.Matchers.CSharpCode</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>wiremock;matchers;matcher;csharp;csharpcode</PackageTags>
<RootNamespace>WireMock</RootNamespace>
@@ -37,16 +37,8 @@
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net452' ">
<PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="3.6.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' or '$(TargetFramework)' == 'net461' ">
<PackageReference Include="CS-Script" Version="3.30.3" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'">
<PackageReference Include="CS-Script" Version="4.8.17" />
<ItemGroup>
<PackageReference Include="CS-Script" Version="4.13.2" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
// Copyright © WireMock.Net
using System;
using System.Collections.Generic;
using WireMock.Matchers.Helpers;
using WireMock.Models.Mime;
using WireMock.Util;
@@ -12,7 +13,7 @@ namespace WireMock.Matchers;
/// </summary>
public class MimePartMatcher : IMimePartMatcher
{
private readonly Func<IMimePartData, MatchResult>[] _funcs;
private readonly IList<(string Name, Func<IMimePartData, MatchResult> func)> _matcherFunctions;
/// <inheritdoc />
public string Name => nameof(MimePartMatcher);
@@ -49,34 +50,47 @@ public class MimePartMatcher : IMimePartMatcher
ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
ContentMatcher = contentMatcher;
_funcs =
[
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition?.ToString()?.Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToLowerInvariant()) ?? MatchScores.Perfect,
MatchOnContent
];
_matcherFunctions = [];
if (ContentTypeMatcher != null)
{
_matcherFunctions.Add((nameof(ContentTypeMatcher), mp => ContentTypeMatcher.IsMatch(GetContentTypeAsString(mp.ContentType))));
}
if (ContentDispositionMatcher != null)
{
_matcherFunctions.Add((nameof(ContentDispositionMatcher), mp => ContentDispositionMatcher.IsMatch(mp.ContentDisposition?.ToString()?.Replace("Content-Disposition: ", string.Empty))));
}
if (ContentTransferEncodingMatcher != null)
{
_matcherFunctions.Add((nameof(ContentTransferEncodingMatcher), mp => ContentTransferEncodingMatcher.IsMatch(mp.ContentTransferEncoding.ToLowerInvariant())));
}
if (ContentMatcher != null)
{
_matcherFunctions.Add((ContentMatcher.Name, MatchOnContent));
}
}
/// <inheritdoc />
public MatchResult IsMatch(IMimePartData value)
{
var score = MatchScores.Mismatch;
Exception? exception = null;
var results = new List<MatchResult>();
try
foreach (var matcherFunction in _matcherFunctions)
{
if (Array.TrueForAll(_funcs, func => func(value).IsPerfect()))
try
{
score = MatchScores.Perfect;
var matchResult = matcherFunction.func(value);
results.Add(MatchResult.From(matcherFunction.Name, matchResult.Score));
}
catch (Exception ex)
{
results.Add(MatchResult.From(matcherFunction.Name, MatchScores.Mismatch, ex));
}
}
catch (Exception ex)
{
exception = ex;
}
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
return MatchResult.From(nameof(MimePartMatcher), results, MatchOperator.And);
}
/// <inheritdoc />
@@ -87,11 +101,6 @@ public class MimePartMatcher : IMimePartMatcher
private MatchResult MatchOnContent(IMimePartData mimePart)
{
if (ContentMatcher == null)
{
return MatchScores.Perfect;
}
var bodyParserSettings = new BodyParserSettings
{
Stream = mimePart.Open(),
@@ -102,7 +111,7 @@ public class MimePartMatcher : IMimePartMatcher
};
var bodyData = BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false).GetAwaiter().GetResult();
return BodyDataMatchScoreCalculator.CalculateMatchScore(bodyData, ContentMatcher);
return BodyDataMatchScoreCalculator.CalculateMatchScore(bodyData, ContentMatcher!);
}
private static string? GetContentTypeAsString(IContentTypeData? contentType)

View File

@@ -135,6 +135,6 @@ internal class MimeMessageDataWrapper : IMimeMessageData
/// <inheritdoc/>
public override string ToString()
{
return _message.ToString();
return _message.ToString() ?? string.Empty;
}
}

View File

@@ -52,7 +52,7 @@ internal class MimeKitUtils : IMimeKitUtils
return false;
}
var fixedBytes = FixBytes(bytes, contentTypeHeader[0]);
var fixedBytes = PrependContentTypeHeader(bytes, contentTypeHeader[0]);
mimeMessageData = LoadFromStream(new MemoryStream(fixedBytes));
return true;
@@ -68,7 +68,10 @@ internal class MimeKitUtils : IMimeKitUtils
return contentTypeHeader.Any(ct => ct.TrimStart().StartsWith("multipart/", StringComparison.OrdinalIgnoreCase));
}
private static byte[] FixBytes(byte[] bytes, WireMockList<string> contentType)
/// <summary>
/// Prepends the Content-Type header to the byte array to make it a valid MIME message for MimeKit.
/// </summary>
private static byte[] PrependContentTypeHeader(byte[] bytes, WireMockList<string> contentType)
{
var contentTypeBytes = Encoding.UTF8.GetBytes($"{HttpKnownHeaderNames.ContentType}: {contentType}\r\n\r\n");

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>MultiPart Mime support for WireMock.Net using MimeKitLite</Description>
<AssemblyTitle>WireMock.Net.MimePart</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>netstandard2.0;netstandard2.1;net462;net47;net48;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>wiremock;matchers;matcher;mime;multipart;mimekit</PackageTags>
<RootNamespace>WireMock</RootNamespace>
@@ -36,24 +36,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Stef.Validation" Version="0.1.1" />
<PackageReference Include="Stef.Validation" Version="0.2.0" />
</ItemGroup>
<!--<ItemGroup>
<PackageReference Include="MimeKitLite" Version="4.12.0" />
</ItemGroup>-->
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="MimeKitLite" Version="4.12.0" />
<PackageReference Include="MimeKitLite" Version="4.13.0" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.40" PrivateAssets="All" />
<PackageReference Include="MimeKitLite" Version="4.12.0" PrivateAssets="All" />
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.43" PrivateAssets="All" />
<PackageReference Include="MimeKitLite" Version="4.13.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,6 +1,5 @@
// Copyright © WireMock.Net
#if !NETSTANDARD1_3
using System;
using System.Diagnostics.CodeAnalysis;
using System.IdentityModel.Tokens.Jwt;
@@ -54,7 +53,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
{
if (string.IsNullOrEmpty(input))
{
return MatchScores.Mismatch;
return MatchResult.From(Name);
}
var token = Regex.Replace(input, BearerPrefix, string.Empty, RegexOptions.IgnoreCase, RegexConstants.DefaultTimeout);
@@ -83,11 +82,11 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
// Throws an Exception as the token is invalid (expired, invalid-formatted, tenant mismatch, etc.)
_jwtSecurityTokenHandler.ValidateToken(token, validationParameters, out _);
return MatchScores.Perfect;
return MatchResult.From(Name, MatchScores.Perfect);
}
catch (Exception ex)
{
return new MatchResult(MatchScores.Mismatch, ex);
return MatchResult.From(Name, ex);
}
}
@@ -111,5 +110,4 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
tenant = null;
return false;
}
}
#endif
}

View File

@@ -1,18 +0,0 @@
// Copyright © WireMock.Net
#if NET451 || NET452 || NET46 || NET451 || NET461 || NETSTANDARD1_3 || NETSTANDARD2_0
using System.Text.RegularExpressions;
using WireMock.Constants;
// ReSharper disable once CheckNamespace
namespace System;
internal static class StringExtensions
{
public static string Replace(this string text, string oldValue, string newValue, StringComparison stringComparison)
{
var options = stringComparison == StringComparison.OrdinalIgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;
return Regex.Replace(text, oldValue, newValue, options, RegexConstants.DefaultTimeout);
}
}
#endif

View File

@@ -1,28 +0,0 @@
// Copyright © WireMock.Net
#if NETSTANDARD1_3
// ReSharper disable once CheckNamespace
namespace System.Net;
internal class WebProxy : IWebProxy
{
private readonly string _proxy;
public ICredentials? Credentials { get; set; }
public WebProxy(string proxy)
{
_proxy = proxy;
}
public Uri GetProxy(Uri destination)
{
return new Uri(_proxy);
}
public bool IsBypassed(Uri host)
{
return true;
}
}
#endif

View File

@@ -11,29 +11,18 @@ internal static class HttpClientBuilder
{
public static HttpClient Build(HttpClientSettings settings)
{
#if NETSTANDARD || NETCOREAPP3_1 || NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
var handler = new HttpClientHandler
{
CheckCertificateRevocationList = false,
#if NET5_0_OR_GREATER
SslProtocols = System.Security.Authentication.SslProtocols.Tls13 | System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
#else
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
#endif
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#elif NET46
#else
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#else
var handler = new WebRequestHandler
{
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#endif
@@ -67,13 +56,12 @@ internal static class HttpClientBuilder
}
}
#if NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
#elif !NETSTANDARD1_3
#else
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
#endif
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
return HttpClientFactory2.Create(handler);
}

View File

@@ -28,7 +28,7 @@ internal static class HttpClientFactory2
var next = handler;
foreach (var delegatingHandler in delegatingHandlers.Reverse())
foreach (var delegatingHandler in Enumerable.Reverse(delegatingHandlers))
{
delegatingHandler.InnerHandler = next;
next = delegatingHandler;

View File

@@ -1,5 +1,6 @@
// Copyright © WireMock.Net
#if NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
using System;
using System.Net.Http;
using WireMock.Server;

View File

@@ -43,11 +43,8 @@ internal static class CertificateLoader
}
finally
{
#if NETSTANDARD || NET46
certStore.Dispose();
#else
certStore.Close();
#endif
}
}
@@ -56,7 +53,7 @@ internal static class CertificateLoader
if (options.X509CertificateFilePath.EndsWith(ExtensionPem, StringComparison.OrdinalIgnoreCase))
{
// PEM logic based on: https://www.scottbrady91.com/c-sharp/pem-loading-in-dotnet-core-and-dotnet
#if NET5_0_OR_GREATER
#if NET8_0_OR_GREATER
if (!string.IsNullOrEmpty(options.X509CertificatePassword))
{
var certPem = File.ReadAllText(options.X509CertificateFilePath);
@@ -66,18 +63,8 @@ internal static class CertificateLoader
return new X509Certificate2(cert.Export(X509ContentType.Pfx, defaultPasswordPem), defaultPasswordPem);
}
return X509Certificate2.CreateFromPemFile(options.X509CertificateFilePath);
#elif NETCOREAPP3_1
var cert = new X509Certificate2(options.X509CertificateFilePath);
if (!string.IsNullOrEmpty(options.X509CertificatePassword))
{
var key = System.Security.Cryptography.ECDsa.Create()!;
key.ImportECPrivateKey(System.Text.Encoding.UTF8.GetBytes(options.X509CertificatePassword), out _);
return cert.CopyWithPrivateKey(key);
}
return cert;
#else
throw new InvalidOperationException("Loading a PEM Certificate is only supported for .NET Core App 3.1, .NET 5.0 and higher.");
throw new InvalidOperationException("Loading a PEM Certificate is only supported for .NET 8.0 and higher.");
#endif
}
@@ -123,11 +110,8 @@ internal static class CertificateLoader
}
finally
{
#if NETSTANDARD || NET46
certStore.Dispose();
#else
certStore.Close();
#endif
}
}
}

View File

@@ -1,6 +1,5 @@
// Copyright © WireMock.Net
using System;
using WireMock.Matchers.Request;
namespace WireMock.Logging;
@@ -14,13 +13,13 @@ public class LogEntry : ILogEntry
public Guid Guid { get; set; }
/// <inheritdoc cref="ILogEntry.RequestMessage" />
public IRequestMessage RequestMessage { get; set; } = null!;
public IRequestMessage? RequestMessage { get; set; }
/// <inheritdoc cref="ILogEntry.ResponseMessage" />
public IResponseMessage ResponseMessage { get; set; } = null!;
public IResponseMessage? ResponseMessage { get; set; }
/// <inheritdoc cref="ILogEntry.RequestMatchResult" />
public IRequestMatchResult RequestMatchResult { get; set; } = null!;
public IRequestMatchResult? RequestMatchResult { get; set; }
/// <inheritdoc cref="ILogEntry.MappingGuid" />
public Guid? MappingGuid { get; set; }
@@ -35,5 +34,5 @@ public class LogEntry : ILogEntry
public string? PartialMappingTitle { get; set; }
/// <inheritdoc cref="ILogEntry.PartialMatchResult" />
public IRequestMatchResult PartialMatchResult { get; set; } = null!;
public IRequestMatchResult? PartialMatchResult { get; set; }
}

View File

@@ -69,7 +69,7 @@ public class WireMockConsoleLogger : IWireMockLogger
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
Console.WriteLine(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Stef.Validation;
using WireMock.Matchers.Request;
using WireMock.Models;
@@ -145,9 +146,9 @@ public class Mapping : IMapping
}
/// <inheritdoc />
public Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IRequestMessage requestMessage)
public Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(HttpContext context, IRequestMessage requestMessage)
{
return Provider.ProvideResponseAsync(this, requestMessage, Settings);
return Provider.ProvideResponseAsync(this, context, requestMessage, Settings);
}
/// <inheritdoc />

View File

@@ -1,9 +1,6 @@
// Copyright © WireMock.Net
using System;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Admin.Mappings;
using WireMock.Matchers.Request;
@@ -164,8 +161,8 @@ public class MappingBuilder : IMappingBuilder
}
}
private static string ToJson(object value)
private string ToJson(object value)
{
return JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsDefault);
return _settings.DefaultJsonSerializer.Serialize(value, JsonSerializationConstants.JsonConverterOptionsDefault);
}
}

Some files were not shown because too many files have changed in this diff Show More