Fix for DateTime Header causing null value in ResponseBuilder #90

Closed
opened 2025-12-29 14:22:09 +01:00 by adam · 19 comments
Owner

Originally created by @rangerranger on GitHub (Apr 10, 2018).

Having the below header in a static mapping file as part of the response results in a NULL value being returned to ResponseBuilder in InitResponseBuilder, since it either expects a string or json - but this header value is being read in as a DateTime object.

"Rate-Limit-Reset": "2018-04-09T20:39:46.956Z",

I added a quickfix like so, please let me know if that looks ok?
In src/WireMock.Net/Server/FluentMockServer.Admin.cs:
747524c03f (diff-8633a9484e8c211d1cc3fc5d0c12f4de)

Originally created by @rangerranger on GitHub (Apr 10, 2018). Having the below header in a static mapping file as part of the response results in a NULL value being returned to ResponseBuilder in InitResponseBuilder, since it either expects a string or json - but this header value is being read in as a DateTime object. "Rate-Limit-Reset": "2018-04-09T20:39:46.956Z", I added a quickfix like so, please let me know if that looks ok? In src/WireMock.Net/Server/FluentMockServer.Admin.cs: https://github.com/rangerranger/WireMock.Net/commit/747524c03fdd79915075e307e11b20795f5ccc69#diff-8633a9484e8c211d1cc3fc5d0c12f4de
adam closed this issue 2025-12-29 14:22:09 +01:00
Author
Owner

@StefH commented on GitHub (Apr 11, 2018):

This quickfix contains two things? JsonExactMatcher code, do you still need that?
And the datetime fix.

Can you make a PR with just the datetime header fix and also add some unittests?

@StefH commented on GitHub (Apr 11, 2018): This quickfix contains two things? JsonExactMatcher code, do you still need that? And the datetime fix. Can you make a PR with just the datetime header fix and also add some unittests?
Author
Owner

@rangerranger commented on GitHub (Apr 11, 2018):

I will add the unit tests for the DateTime fix and create a separate PR. As to the ExactJsonMatcher - please can you tell me how to correctly use the JsonPathMatcher if we want to just record request/responses via proxy WireMock and then use them to mock? In that case the JsonPathMatcher is not matching the subsequent requests even when they are exact same Json, Does the recording need to be changed to some JsonPath syntax after recording? Thank you Stef.

@rangerranger commented on GitHub (Apr 11, 2018): I will add the unit tests for the DateTime fix and create a separate PR. As to the ExactJsonMatcher - please can you tell me how to correctly use the JsonPathMatcher if we want to just record request/responses via proxy WireMock and then use them to mock? In that case the JsonPathMatcher is not matching the subsequent requests even when they are exact same Json, Does the recording need to be changed to some JsonPath syntax after recording? Thank you Stef.
Author
Owner

@StefH commented on GitHub (Apr 11, 2018):

If using WireMock to proxy request, please take a look at this code here:

https://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.Console.Proxy.Net452/Program.cs

Change this code

SaveMapping = true,
SaveMappingToFile = true

This will save each request and response in a file.

I hope this helps?

@StefH commented on GitHub (Apr 11, 2018): If using WireMock to proxy request, please take a look at this code here: https://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.Console.Proxy.Net452/Program.cs Change this code ``` c# SaveMapping = true, SaveMappingToFile = true ``` This will save each request and response in a file. I hope this helps?
Author
Owner

@rangerranger commented on GitHub (Apr 11, 2018):

I think i didnt explain clearly. I am able to proxy and record. But when using the recorded mapping files for mocking, the jsonpathmapper never matches the requests - same requests that were recorded. Thats the reason i created the JsonExactMatcher. Is there something im doing wrong in using JsonPathMapper if i want it to match the complete json in the recorded request exactly?

On Apr 11, 2018, at 12:00 PM, Stef Heyenrath notifications@github.com wrote:

If using WireMock to proxy request, please take a look at this code here:

https://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.Console.Proxy.Net452/Program.cs

Change this code

SaveMapping = true,
SaveMappingToFile = true
This will save each request and response in a file.

I hope this helps?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@rangerranger commented on GitHub (Apr 11, 2018): I think i didnt explain clearly. I am able to proxy and record. But when using the recorded mapping files for mocking, the jsonpathmapper never matches the requests - same requests that were recorded. Thats the reason i created the JsonExactMatcher. Is there something im doing wrong in using JsonPathMapper if i want it to match the complete json in the recorded request exactly? > On Apr 11, 2018, at 12:00 PM, Stef Heyenrath <notifications@github.com> wrote: > > If using WireMock to proxy request, please take a look at this code here: > > https://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.Console.Proxy.Net452/Program.cs > > Change this code > > SaveMapping = true, > SaveMappingToFile = true > This will save each request and response in a file. > > I hope this helps? > > — > You are receiving this because you authored the thread. > Reply to this email directly, view it on GitHub, or mute the thread. >
Author
Owner

@StefH commented on GitHub (Apr 11, 2018):

Ok I see.

When using the saved request, sometimes it's needed to manually adjust the mapping a bit because the matching is too strict because not only the body is matched but also headers, query and others.

Make sure to enable partial mapping and then do a http get request to /__admin/requests to see the matching details from the request you did send. Look for matchings where the match is 0.

@StefH commented on GitHub (Apr 11, 2018): Ok I see. When using the saved request, sometimes it's needed to manually adjust the mapping a bit because the matching is too strict because not only the body is matched but also headers, query and others. Make sure to enable partial mapping and then do a http get request to /__admin/requests to see the matching details from the request you did send. Look for matchings where the match is 0.
Author
Owner

@rangerranger commented on GitHub (Apr 11, 2018):

Right. Still keeping PartialMatching to FALSE, i can match with JsonExactMatcher but not with JsonPathMatcher. Not sure why - couldnt get JsonPathMatcher to work. Therefore wrote the simple JsonExactMatcher. I can send you the mapping file as an example repro if uou want - but JsonPathMatcher returns score 0.

On Apr 11, 2018, at 12:46 PM, Stef Heyenrath notifications@github.com wrote:

Ok I see.

When using the saved request, sometimes it's needed to manually adjust the mapping a bit because the matching is too strict because not only the body is matched but also headers, query and others.

Make sure to enable partial mapping and then do a http get request to /__admin/requests to see the matching details from the request you did send. Look for matchings where the match is 0.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@rangerranger commented on GitHub (Apr 11, 2018): Right. Still keeping PartialMatching to FALSE, i can match with JsonExactMatcher but not with JsonPathMatcher. Not sure why - couldnt get JsonPathMatcher to work. Therefore wrote the simple JsonExactMatcher. I can send you the mapping file as an example repro if uou want - but JsonPathMatcher returns score 0. > On Apr 11, 2018, at 12:46 PM, Stef Heyenrath <notifications@github.com> wrote: > > Ok I see. > > When using the saved request, sometimes it's needed to manually adjust the mapping a bit because the matching is too strict because not only the body is matched but also headers, query and others. > > Make sure to enable partial mapping and then do a http get request to /__admin/requests to see the matching details from the request you did send. Look for matchings where the match is 0. > > — > You are receiving this because you authored the thread. > Reply to this email directly, view it on GitHub, or mute the thread. >
Author
Owner

@StefH commented on GitHub (Apr 15, 2018):

Please create a sample project, so I can analyze.

@StefH commented on GitHub (Apr 15, 2018): Please create a sample project, so I can analyze.
Author
Owner

@StefH commented on GitHub (May 18, 2018):

From now on it's also possible to use a simple Wildcard (string-matcher) for JSON messages, will this help you in this case?

@StefH commented on GitHub (May 18, 2018): From now on it's also possible to use a simple Wildcard (string-matcher) for JSON messages, will this help you in this case?
Author
Owner

@rangerranger commented on GitHub (May 21, 2018):

Hi Stef, apologies for the late response (have been slammed). Yes that
would be a great addition indeed. What I discovered was that while proxy
recording
, the body (or bodyasjson or bodyasbytes) in the request is not
recorded. And hence when we try to match with a specific body difference it
is not available in the mapping.
I can understand why this is the case, as the library wouldnt know what
matcher to use (esp for bodyasbytes).
While I added a matcher that is useful for our work and put it in the
library, that is not an extensible approach.
Instead could we have a mechanism where a matcher is created outside the
library and provided to the FluentServer as part of the settings? Just like
for the logger.
There can be a CustomBodyMatcher, CustomBodyAsJsonMatcher and
CustomBodyAsBytes matcher fields in the FluentServerSettings, which are
then used during recording. Similarly they would have to be passed in also
for standard mocking (ie non-proxy server).
Thoughts?
Aroon

On Fri, May 18, 2018 at 12:00 AM, Stef Heyenrath notifications@github.com
wrote:

From now on it's also possible to use a simple Wildcard (string-matcher)
for JSON messages, will this help you in this case?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/WireMock-Net/WireMock.Net/issues/123#issuecomment-390114214,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AkdXDh2zD0N8aHtmet08lO2kwhqdQh3eks5tznGbgaJpZM4TPEF7
.

@rangerranger commented on GitHub (May 21, 2018): Hi Stef, apologies for the late response (have been slammed). Yes that would be a great addition indeed. What I discovered was that while *proxy recording*, the body (or bodyasjson or bodyasbytes) in the *request* is not recorded. And hence when we try to match with a specific body difference it is not available in the mapping. I can understand why this is the case, as the library wouldnt know what matcher to use (esp for bodyasbytes). While I added a matcher that is useful for our work and put it in the library, that is not an extensible approach. Instead could we have a mechanism where a matcher is created outside the library and provided to the FluentServer as part of the settings? Just like for the logger. There can be a CustomBodyMatcher, CustomBodyAsJsonMatcher and CustomBodyAsBytes matcher fields in the FluentServerSettings, which are then used during recording. Similarly they would have to be passed in also for standard mocking (ie non-proxy server). Thoughts? Aroon On Fri, May 18, 2018 at 12:00 AM, Stef Heyenrath <notifications@github.com> wrote: > From now on it's also possible to use a simple Wildcard (string-matcher) > for JSON messages, will this help you in this case? > > — > You are receiving this because you authored the thread. > Reply to this email directly, view it on GitHub > <https://github.com/WireMock-Net/WireMock.Net/issues/123#issuecomment-390114214>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/AkdXDh2zD0N8aHtmet08lO2kwhqdQh3eks5tznGbgaJpZM4TPEF7> > . >
Author
Owner

@StefH commented on GitHub (May 21, 2018):

Hello @rangerranger,

1]
When running in proxy mode with these settings:

SaveMapping = true,
SaveMappingToFile = true,

The request is recorded (and saved in the __admin\mappings folder). And the original body (when doing a request which has a body) is also recorded like:

"Body": {
      "Matcher": {
        "Name": "ExactMatcher",
        "Pattern": "{\n\t\"test\": 42\n}"
      }
}

However, the ExactMatcher is always used, you have to manually adjust it to the mapper you would like to use.

2]
A CustomBodyMatcher, CustomBodyAsJsonMatcher and CustomBodyAsBytes can be added to settings, but do you still need these when you read point 1 above?

@StefH commented on GitHub (May 21, 2018): Hello @rangerranger, **1]** When running in proxy mode with these settings: ``` c# SaveMapping = true, SaveMappingToFile = true, ``` The request is recorded (and saved in the `__admin\mappings` folder). And the original body (when doing a request which has a body) is also recorded like: ``` js "Body": { "Matcher": { "Name": "ExactMatcher", "Pattern": "{\n\t\"test\": 42\n}" } } ``` However, the `ExactMatcher` is always used, you have to manually adjust it to the mapper you would like to use. **2]** A `CustomBodyMatcher`, `CustomBodyAsJsonMatcher` and `CustomBodyAsBytes` can be added to settings, but do you still need these when you read point 1 above?
Author
Owner

@rangerranger commented on GitHub (May 21, 2018):

Hi Stef,
For Point 1] - I believe that is currently happening only for "Body" - not
bodyasjson or bodyasbytes. At least in 1.0.3.15. Not sure if you recently
changed.
See in Server\FluentServer.Admin.cs:
if (requestMessage.Body != null)
{
request.WithBody(new ExactMatcher(requestMessage.Body));
}
The other conditional blocks are empty for BodyAsJson and BodyAsBytes. So
my recordings with json content were not recorded body patterns.

For point 2]:
The general problem is that sometimes the body has unique properties which
one may want to selectively ignore, for the match.
In the case of text (body or bodyasjson) this could be somewhat solved by
existing Wildcard or Regex matcher (although the regex matcher may have
some trouble due to the json formatting characters which are also regex
special characters).
And likely impossible for bodyasbytes without the ability to interpret
those bytes. The client invoking the FluentServer will have the ability to
understand the bytes and could provide a custom matcher.

This was my thinking.

Aroon

On Sun, May 20, 2018 at 11:27 PM, Stef Heyenrath notifications@github.com
wrote:

Hello @rangerranger https://github.com/rangerranger,

1]
When running in proxy mode with these settings:

SaveMapping = true,SaveMappingToFile = true,

The request is recorded (and saved in the __admin\mappings folder). And
the original body (when doing a request which has a body) is also recorded
like:

"Body": {
"Matcher": {
"Name": "ExactMatcher",
"Pattern": "{\n\t"test": 42\n}"
}
}

However, the ExactMatcher is always used, you have to manually adjust it
to the mapper you would like to use.

2]
A CustomBodyMatcher, CustomBodyAsJsonMatcher and CustomBodyAsBytes can be
added to settings, but do you still need these when you read point 1 above?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/WireMock-Net/WireMock.Net/issues/123#issuecomment-390564922,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AkdXDpVn2Q0rVan-_0BQe7o7-9BISd-Gks5t0l5QgaJpZM4TPEF7
.

@rangerranger commented on GitHub (May 21, 2018): Hi Stef, For Point 1] - I believe that is currently happening only for "Body" - not bodyasjson or bodyasbytes. At least in 1.0.3.15. Not sure if you recently changed. See in Server\FluentServer.Admin.cs: if (requestMessage.Body != null) { request.WithBody(new ExactMatcher(requestMessage.Body)); } The other conditional blocks are empty for BodyAsJson and BodyAsBytes. So my recordings with json content were not recorded body patterns. For point 2]: The general problem is that sometimes the body has unique properties which one may want to *selectively* ignore, for the match. In the case of text (body or bodyasjson) this could be somewhat solved by existing Wildcard or Regex matcher (although the regex matcher may have some trouble due to the json formatting characters which are also regex special characters). And likely impossible for bodyasbytes without the ability to interpret those bytes. The client invoking the FluentServer will have the ability to understand the bytes and could provide a custom matcher. This was my thinking. Aroon On Sun, May 20, 2018 at 11:27 PM, Stef Heyenrath <notifications@github.com> wrote: > Hello @rangerranger <https://github.com/rangerranger>, > > 1] > When running in proxy mode with these settings: > > SaveMapping = true,SaveMappingToFile = true, > > The request is recorded (and saved in the __admin\mappings folder). And > the original body (when doing a request which has a body) is also recorded > like: > > "Body": { > "Matcher": { > "Name": "ExactMatcher", > "Pattern": "{\n\t\"test\": 42\n}" > } > } > > However, the ExactMatcher is always used, you have to manually adjust it > to the mapper you would like to use. > > 2] > A CustomBodyMatcher, CustomBodyAsJsonMatcher and CustomBodyAsBytes can be > added to settings, but do you still need these when you read point 1 above? > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > <https://github.com/WireMock-Net/WireMock.Net/issues/123#issuecomment-390564922>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/AkdXDpVn2Q0rVan-_0BQe7o7-9BISd-Gks5t0l5QgaJpZM4TPEF7> > . >
Author
Owner

@StefH commented on GitHub (May 21, 2018):

Hi Aroon,

1]
The code block you mention is not changed in latest releases. However I think the proxy code works fine.

When you post a string as body, or a json string, the body is added to the request and the exact string is added as pattern and exact matcher is used.

So when I send this using postman:
post

I get exactly what I posted in option 1 above.

Now it's up to the user from WireMock to analyze the whole request, and check if some thing need changing. In order to craft the correct mapping.

2]
The bodyasbytes is not supported as is, but I believe that when you send a binary using post, the body is recorded as base64.

3]
When you want custom matchers, you can just use one of the Func methods:

/// <summary>
/// WithBody: func (string)
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<string, bool> func);

/// <summary>
/// WithBody: func (byte[])
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<byte[], bool> func);

/// <summary>
/// WithBody: func (object)
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<object, bool> func);

See a8ddd31c9c/src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs (L48)

@StefH commented on GitHub (May 21, 2018): Hi Aroon, 1] The code block you mention is not changed in latest releases. However I think the proxy code works fine. When you post a string as body, or a json string, the body is added to the request and the exact string is added as pattern and exact matcher is used. So when I send this using postman: ![post](https://user-images.githubusercontent.com/249938/40310571-802993dc-5d0d-11e8-957c-2722c92bb14d.png) I get exactly what I posted in option 1 above. Now it's up to the user from WireMock to analyze the whole request, and check if some thing need changing. In order to craft the correct mapping. 2] The bodyasbytes is not supported as is, but I believe that when you send a binary using post, the body is recorded as base64. 3] When you want custom matchers, you can just use one of the `Func` methods: ``` c# /// <summary> /// WithBody: func (string) /// </summary> /// <param name="func">The function.</param> /// <returns>The <see cref="IRequestBuilder"/>.</returns> IRequestBuilder WithBody([NotNull] Func<string, bool> func); /// <summary> /// WithBody: func (byte[]) /// </summary> /// <param name="func">The function.</param> /// <returns>The <see cref="IRequestBuilder"/>.</returns> IRequestBuilder WithBody([NotNull] Func<byte[], bool> func); /// <summary> /// WithBody: func (object) /// </summary> /// <param name="func">The function.</param> /// <returns>The <see cref="IRequestBuilder"/>.</returns> IRequestBuilder WithBody([NotNull] Func<object, bool> func); ``` See https://github.com/WireMock-Net/WireMock.Net/blob/a8ddd31c9ce3a77d3c6c32df7f0d6652a3727fd4/src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs#L48
Author
Owner

@StefH commented on GitHub (May 28, 2018):

Hello @rangerranger : Is my post above clear ?

@StefH commented on GitHub (May 28, 2018): Hello @rangerranger : Is my post above clear ?
Author
Owner

@rangerranger commented on GitHub (May 28, 2018):

Hi Stef, does the recording of json in body work when you set content-type header as application/json? I believe it puts the content in bodyAsJson member of the request object and the body is empty in recorded mapping.

With regards to custom matchers and your suggestion of using func: im not sure how it would work for recorded mappings?

Aroon

On May 28, 2018, at 6:12 AM, Stef Heyenrath notifications@github.com wrote:

Hello @rangerranger : Is my post above clear ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@rangerranger commented on GitHub (May 28, 2018): Hi Stef, does the recording of json in body work when you set content-type header as application/json? I believe it puts the content in bodyAsJson member of the request object and the body is empty in recorded mapping. With regards to custom matchers and your suggestion of using func: im not sure how it would work for recorded mappings? Aroon > On May 28, 2018, at 6:12 AM, Stef Heyenrath <notifications@github.com> wrote: > > Hello @rangerranger : Is my post above clear ? > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub, or mute the thread.
Author
Owner

@StefH commented on GitHub (May 28, 2018):

a] The recording of any body should work, you don't need to use that content-type.

b] Correct. You cannot use that directly. There is no possible way yet to convert a recorded mapping (json) into the C# code which defines that mapping. I can investigate if this is easy to build...

@StefH commented on GitHub (May 28, 2018): a] The recording of **any** body should work, you don't need to use that content-type. b] Correct. You cannot use that directly. There is no possible way yet to convert a recorded mapping (json) into the C# code which defines that mapping. I can investigate if this is easy to build...
Author
Owner

@rangerranger commented on GitHub (May 28, 2018):

My testing shows that if the application being mocked(recorded) sets the application/json header then the body is not recorded. If i remember that was because the body content is placed in BodyAsJson and that segment of wiremock code is empty. I could ld be wrong, can test again.

On May 28, 2018, at 9:38 AM, Stef Heyenrath notifications@github.com wrote:

a] The recording of any body should work, you don't need to use that content-type.

b] Correct. You cannot use that directly. There is no possible way yet to convert a recorded mapping (json) into the C# code which defines that mapping. I can investigate if this is easy to build...


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@rangerranger commented on GitHub (May 28, 2018): My testing shows that if the application being mocked(recorded) sets the application/json header then the body is not recorded. If i remember that was because the body content is placed in BodyAsJson and that segment of wiremock code is empty. I could ld be wrong, can test again. > On May 28, 2018, at 9:38 AM, Stef Heyenrath <notifications@github.com> wrote: > > a] The recording of any body should work, you don't need to use that content-type. > > b] Correct. You cannot use that directly. There is no possible way yet to convert a recorded mapping (json) into the C# code which defines that mapping. I can investigate if this is easy to build... > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub, or mute the thread.
Author
Owner

@StefH commented on GitHub (May 28, 2018):

A quick question: you are using a POST or PUT request ?

@StefH commented on GitHub (May 28, 2018): A quick question: you are using a POST or PUT request ?
Author
Owner

@rangerranger commented on GitHub (May 28, 2018):

Hi Stef - POST.

On May 28, 2018, at 9:59 AM, Stef Heyenrath notifications@github.com wrote:

A quick question: you are using a POST or PUT request ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@rangerranger commented on GitHub (May 28, 2018): Hi Stef - POST. > On May 28, 2018, at 9:59 AM, Stef Heyenrath <notifications@github.com> wrote: > > A quick question: you are using a POST or PUT request ? > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub, or mute the thread.
Author
Owner

@StefH commented on GitHub (Jul 2, 2018):

Latest version support a new matcher : JsonMatcher which can be used to match a json body 1:1.

See also https://github.com/WireMock-Net/WireMock.Net/issues/154

I'm closing this issue now, please open a new one with details if you still have issues.

Or start a chat at https://gitter.im/wiremock_dotnet/Lobby

@StefH commented on GitHub (Jul 2, 2018): Latest version support a new matcher : `JsonMatcher` which can be used to match a json body 1:1. See also https://github.com/WireMock-Net/WireMock.Net/issues/154 I'm closing this issue now, please open a new one with details if you still have issues. Or start a chat at https://gitter.im/wiremock_dotnet/Lobby
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#90