Matching one form-urlencoded value #497

Closed
opened 2025-12-29 08:29:06 +01:00 by adam · 17 comments
Owner

Originally created by @terryaney on GitHub (Mar 13, 2023).

Originally assigned to: @StefH on GitHub.

If I have a IRequestBuilder, what do I do to make it only match when a single, specific form key/value is set?

Originally created by @terryaney on GitHub (Mar 13, 2023). Originally assigned to: @StefH on GitHub. If I have a `IRequestBuilder`, what do I do to make it only match when a single, specific form key/value is set?
adam added the feature label 2025-12-29 08:29:06 +01:00
adam closed this issue 2025-12-29 08:29:06 +01:00
Author
Owner

@StefH commented on GitHub (Mar 14, 2023):

Can you please give an example?

@StefH commented on GitHub (Mar 14, 2023): Can you please give an example?
Author
Owner

@terryaney commented on GitHub (Mar 14, 2023):

Well, below is what I came up with as a helper...where r is my own object and it optionally has a Dictionary<string, string> FormValues property. If I set this property with a a dictionary of one or more items, I then make sure that the form value is present. I've only just started using WireMock so no idea if there are better solutions, but it seems to be working.

Func<IBodyData, bool> bodyMatcher = body =>
{
	var formValues =
		body.BodyAsString!.Split( '&' )
			.Select( p => p.Split( '=' ) )
			.ToDictionary( k => k[ 0 ], v => WebUtility.UrlDecode( v[ 1 ] ) );

	foreach( var k in r.FormValues.Keys )
	{
		if ( !formValues.ContainsKey( k ) || formValues[ k ] != r.FormValues[ k ] )
		{
			return false;
		}
	}
	return true;
};

request.WithBody( bodyMatcher );
@terryaney commented on GitHub (Mar 14, 2023): Well, below is what I came up with as a helper...where `r` is my own object and it optionally has a `Dictionary<string, string> FormValues` property. If I set this property with a a dictionary of one or more items, I then make sure that the form value is present. I've only just started using WireMock so no idea if there are better solutions, but it seems to be working. ``` c# Func<IBodyData, bool> bodyMatcher = body => { var formValues = body.BodyAsString!.Split( '&' ) .Select( p => p.Split( '=' ) ) .ToDictionary( k => k[ 0 ], v => WebUtility.UrlDecode( v[ 1 ] ) ); foreach( var k in r.FormValues.Keys ) { if ( !formValues.ContainsKey( k ) || formValues[ k ] != r.FormValues[ k ] ) { return false; } } return true; }; request.WithBody( bodyMatcher ); ```
Author
Owner

@StefH commented on GitHub (Mar 14, 2023):

Your request contains a header "x-www-form-urlencoded" and the body looks like:

username=abc&password=123

?

@StefH commented on GitHub (Mar 14, 2023): Your request contains a header "x-www-form-urlencoded" and the body looks like: ``` username=abc&password=123 ``` ?
Author
Owner

@StefH commented on GitHub (Mar 15, 2023):

https://github.com/WireMock-Net/WireMock.Net/pull/903

@StefH commented on GitHub (Mar 15, 2023): https://github.com/WireMock-Net/WireMock.Net/pull/903
Author
Owner

@StefH commented on GitHub (Mar 15, 2023):

@terryaney

You should now be able to use WithBody(Func<IDictionary<string, string>?, bool> func);

Use NuGet preview version : 1.5.18-ci-17167

Info --> https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions

@StefH commented on GitHub (Mar 15, 2023): @terryaney You should now be able to use `WithBody(Func<IDictionary<string, string>?, bool> func);` Use NuGet preview version : `1.5.18-ci-17167` Info --> https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions
Author
Owner

@terryaney commented on GitHub (Mar 15, 2023):

Your request contains a header "x-www-form-urlencoded" and the body looks like:

username=abc&password=123

?

As you've probably guessed, yes, that is what IBodyData.BodyAsString returned.

@terryaney commented on GitHub (Mar 15, 2023): > Your request contains a header "x-www-form-urlencoded" and the body looks like: > > ``` > username=abc&password=123 > ``` > > ? As you've probably guessed, yes, that is what `IBodyData.BodyAsString` returned.
Author
Owner

@StefH commented on GitHub (Mar 15, 2023):

Did you manage to install the preview?

@StefH commented on GitHub (Mar 15, 2023): Did you manage to install the preview?
Author
Owner

@terryaney commented on GitHub (Mar 15, 2023):

Did you manage to install the preview?

No....

image

Then when I go to NuGet Gallery and pick WireMock.Net...

image

I'm not seeing anything in any of the 'output windows'. Any idea where to look for diagnostic info? I guess I could maybe try the cli, assuming there is a way to specify which NuGet source to use.

@terryaney commented on GitHub (Mar 15, 2023): > Did you manage to install the preview? No.... ![image](https://user-images.githubusercontent.com/6237247/225392278-718c113f-c647-4cf4-bad6-be9dbdd15148.png) Then when I go to NuGet Gallery and pick WireMock.Net... ![image](https://user-images.githubusercontent.com/6237247/225392475-68a34d57-e282-4fcf-bd58-e7024ac23970.png) I'm not seeing anything in any of the 'output windows'. Any idea where to look for diagnostic info? I guess I could maybe try the cli, assuming there is a way to specify which NuGet source to use.
Author
Owner

@StefH commented on GitHub (Mar 15, 2023):

@terryaney

Make sure to select "preview":

image

@StefH commented on GitHub (Mar 15, 2023): @terryaney Make sure to select "preview": ![image](https://user-images.githubusercontent.com/249938/225444778-955808f2-7015-4f7e-a301-322fc7d29651.png)
Author
Owner

@terryaney commented on GitHub (Mar 15, 2023):

Hmm, the same. Wonder if VS Code has different 'schema' or something?

image

@terryaney commented on GitHub (Mar 15, 2023): Hmm, the same. Wonder if VS Code has different 'schema' or something? ![image](https://user-images.githubusercontent.com/6237247/225456108-c3a993db-2227-4eb5-9156-fa98980ca5f5.png)
Author
Owner

@StefH commented on GitHub (Mar 16, 2023):

@terryaney
It seems that custom sources (at least MyGet) is not (yet) supported. (https://github.com/pcislo/vscode-nuget-gallery/issues/19)

For now if you want to keep working in VSCode, you can add a nuget.config file :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="MyGet-WireMock.Net" value="https://www.myget.org/F/wiremock-net/api/v3/index.json" />
  </packageSources>
</configuration>
@StefH commented on GitHub (Mar 16, 2023): @terryaney It seems that custom sources (at least MyGet) is not (yet) supported. (https://github.com/pcislo/vscode-nuget-gallery/issues/19) For now if you want to keep working in VSCode, you can add a nuget.config file : ``` xml <?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="MyGet-WireMock.Net" value="https://www.myget.org/F/wiremock-net/api/v3/index.json" /> </packageSources> </configuration> ```
Author
Owner

@terryaney commented on GitHub (Mar 16, 2023):

Wow this is hard :) Still no love.

No WireMock.Net in dropdown, not sure if there is supposed to be...and neither dotnet-WireMock or WireMock.Net have 1.5.18-* versions.

image

My NuGet.config looks like this, you can see the path in the bread crumbs...I assume that is the file you wanted me to modify and additionally, I added in activePackageSource as well when it wasn't working in 'only' the packageSources, but neither attempt worked.

image

I guess I can just wait until you release a proper version or if you want to drop a dll that I should replace here I could try that too if you wanted me to test it for you.

@terryaney commented on GitHub (Mar 16, 2023): Wow this is hard :) Still no love. No WireMock.Net in dropdown, not sure if there is supposed to be...and neither `dotnet-WireMock` or `WireMock.Net` have 1.5.18-* versions. ![image](https://user-images.githubusercontent.com/6237247/225755260-bf64a7b9-def8-473f-a469-54706a43135e.png) My NuGet.config looks like this, you can see the path in the bread crumbs...I assume that is the file you wanted me to modify and additionally, I added in `activePackageSource` as well when it wasn't working in 'only' the `packageSources`, but neither attempt worked. ![image](https://user-images.githubusercontent.com/6237247/225755491-8fbcfeb1-05cf-47e9-9c0c-10cd4a77ebec.png) I guess I can just wait until you release a proper version or if you want to drop a dll that I should replace here I could try that too if you wanted me to test it for you.
Author
Owner

@StefH commented on GitHub (Mar 17, 2023):

I've added this unit test:

[Fact]
    public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFunc()
    {
        // Arrange
        var server = WireMockServer.Start();
        server.Given(
            Request.Create()
                .UsingPost()
                .WithPath("/foo")
                .WithBody(values => values != null && values["key1"] == "value1")
            )
            .RespondWith(
                Response.Create()
            );

        // Act
        var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("key1", "value1") });
        var response = await new HttpClient()
            .PostAsync($"{server.Url}/foo", content)
            .ConfigureAwait(false);

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.OK);

        server.Stop();
    }

Which scenario you also will use I think.

A new normal NuGet version will be released later today / tomorrow.

@StefH commented on GitHub (Mar 17, 2023): I've added this unit test: ``` c# [Fact] public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFunc() { // Arrange var server = WireMockServer.Start(); server.Given( Request.Create() .UsingPost() .WithPath("/foo") .WithBody(values => values != null && values["key1"] == "value1") ) .RespondWith( Response.Create() ); // Act var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("key1", "value1") }); var response = await new HttpClient() .PostAsync($"{server.Url}/foo", content) .ConfigureAwait(false); // Assert response.StatusCode.Should().Be(HttpStatusCode.OK); server.Stop(); } ``` Which scenario you also will use I think. A new normal NuGet version will be released later today / tomorrow.
Author
Owner

@StefH commented on GitHub (Mar 17, 2023):

https://github.com/WireMock-Net/WireMock.Net/pull/903

@StefH commented on GitHub (Mar 17, 2023): https://github.com/WireMock-Net/WireMock.Net/pull/903
Author
Owner

@terryaney commented on GitHub (Mar 22, 2023):

Thanks for the update. I tested, and I think you need to use WebUtility.UrlDecode for the values?

values[ k ] != r.FormValues[ k ]
true
values[ k ]
"rNaCP7hv8UOmS%2FJcujdvLw%3D%3D"
r.FormValues[ k ]
"rNaCP7hv8UOmS/JcujdvLw=="

values is your Dictionary and FormValues is my setup dictionary. Let me know what you think.

@terryaney commented on GitHub (Mar 22, 2023): Thanks for the update. I tested, and I think you need to use `WebUtility.UrlDecode` for the values? ``` values[ k ] != r.FormValues[ k ] true values[ k ] "rNaCP7hv8UOmS%2FJcujdvLw%3D%3D" r.FormValues[ k ] "rNaCP7hv8UOmS/JcujdvLw==" ``` `values` is your Dictionary and `FormValues` is my setup dictionary. Let me know what you think.
Author
Owner

@StefH commented on GitHub (Mar 22, 2023):

@terryaney
Thanks for testing, you are correct. I'll fix this and release a new version.

@StefH commented on GitHub (Mar 22, 2023): @terryaney Thanks for testing, you are correct. I'll fix this and release a new version.
Author
Owner

@StefH commented on GitHub (Mar 22, 2023):

new NuGet should be available soon

@StefH commented on GitHub (Mar 22, 2023): new NuGet should be available soon
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net#497