Feature: Add support to recognise custom json media-types #145

Closed
opened 2025-12-29 14:23:33 +01:00 by adam · 26 comments
Owner

Originally created by @alefranz on GitHub (Oct 9, 2018).

Originally assigned to: @StefH on GitHub.

Hi,

This is a feature request to add support to recognise as json custom media types:
e.g. application/vnd.*+json.

I think it could be either match on this pattern (or just +json) or open the BodyParser so it can be customized or media-types can be registered.

Specifically I'm after the ability to correctly save the payload as json when saving the auto generated mappings (when capturing as proxy).

If you are open to the idea I can contribute a PR for this.

Originally created by @alefranz on GitHub (Oct 9, 2018). Originally assigned to: @StefH on GitHub. Hi, This is a feature request to add support to recognise as json custom media types: e.g. `application/vnd.*+json`. I think it could be either match on this pattern (or just +json) or open the `BodyParser` so it can be customized or media-types can be registered. Specifically I'm after the ability to correctly save the payload as json when saving the auto generated mappings (when capturing as proxy). If you are open to the idea I can contribute a PR for this.
adam closed this issue 2025-12-29 14:23:33 +01:00
Author
Owner

@StefH commented on GitHub (Oct 9, 2018):

Or define at the mapping that the request body should be parsed as String, Json or Bytes by using a new property at the body mapping named ParseBodyAs.

Using this new setting overrides the default Content-Type logic.

Example

{
    "Guid": "debaf408-3b23-4c04-9d18-ef1c020e79f3",
    "Request": {
        "Path": {
            "Matchers": [
                {
                    "Name": "WildcardMatcher",
                    "Pattern": "/jsonbodytest2",
                    "IgnoreCase": true
                }
            ]
        },
        "Methods": [
            "post"
        ],
        "Body": {
            "ParseBodyAs": "Json",
            "Matcher": {
                "Name": "JsonMatcher",
                "Pattern": {
                  "x": 42,
                  "s": "s"
                }
            }
        }
    },
    "Response": {
        "StatusCode": 200,
        "Body": "{ \"result\": \"jsonbodytest2\" }"
    }
}
@StefH commented on GitHub (Oct 9, 2018): Or define at the mapping that the request body should be parsed as String, Json or Bytes by using a new property at the body mapping named `ParseBodyAs`. Using this new setting overrides the default Content-Type logic. Example ``` js { "Guid": "debaf408-3b23-4c04-9d18-ef1c020e79f3", "Request": { "Path": { "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "/jsonbodytest2", "IgnoreCase": true } ] }, "Methods": [ "post" ], "Body": { "ParseBodyAs": "Json", "Matcher": { "Name": "JsonMatcher", "Pattern": { "x": 42, "s": "s" } } } }, "Response": { "StatusCode": 200, "Body": "{ \"result\": \"jsonbodytest2\" }" } } ```
Author
Owner

@lesnes commented on GitHub (Oct 10, 2018):

i am very interested in this new feature (ParseBodyAs). currently, BodyParser only supports parsing as string for certain content types. this means that one cannot use IStringMatcher implementations for matching request Body when content type is something like multipart/form-data.

when do you expect to release a new version to nuget that includes this functionality ? is it on a branch that i could take a look at?

@lesnes commented on GitHub (Oct 10, 2018): i am very interested in this new feature (`ParseBodyAs`). currently, `BodyParser` only supports parsing as `string` for certain content types. this means that one cannot use `IStringMatcher` implementations for matching request `Body` when content type is something like `multipart/form-data`. when do you expect to release a new version to nuget that includes this functionality ? is it on a branch that i could take a look at?
Author
Owner

@StefH commented on GitHub (Oct 10, 2018):

I'll take a look and start building this new functionality.

@StefH commented on GitHub (Oct 10, 2018): I'll take a look and start building this new functionality.
Author
Owner

@lesnes commented on GitHub (Oct 10, 2018):

that would be great, thanks!

@lesnes commented on GitHub (Oct 10, 2018): that would be great, thanks!
Author
Owner

@alefranz commented on GitHub (Oct 10, 2018):

@StefH is there a way to specify ParseBodyAs with the fluent syntax? and what about in the ProxyAndRecordSettings?

@alefranz commented on GitHub (Oct 10, 2018): @StefH is there a way to specify `ParseBodyAs` with the fluent syntax? and what about in the ProxyAndRecordSettings?
Author
Owner

@StefH commented on GitHub (Oct 10, 2018):

Hello @lesnes and @alefranz,
I'm currently working on a PR https://github.com/WireMock-Net/WireMock.Net/pull/212 which updates the logic for the body parser.

In short:

  • Using a IStringMatcher will always work because the BodyAsString is always filled.
  • Using a IObjectMatcher like JsonMatcher, JsonPathMatcher and LinqMatcher will work in case it's a Json object

Please have a look to see if this will solve your questions.

@StefH commented on GitHub (Oct 10, 2018): Hello @lesnes and @alefranz, I'm currently working on a PR https://github.com/WireMock-Net/WireMock.Net/pull/212 which updates the logic for the body parser. In short: * Using a `IStringMatcher` will always work because the BodyAsString is always filled. * Using a `IObjectMatcher` like `JsonMatcher`, `JsonPathMatcher` and `LinqMatcher` will work in case it's a Json object Please have a look to see if this will solve your questions.
Author
Owner

@alefranz commented on GitHub (Oct 10, 2018):

In the current version I believe sometimes you only have the body as bytes.
Also matching a json with a string is often a pain as the sample response data for the mock are usually not minified, so in my scenario I still need the ability to change something in DetectBodyTypeFromContentType to be able to set custom media type as json.
Ideally would be nice for that class to not be static and the library support to extend it but that seems quite a lot of work. What about using a regex and testing against application/vnd\..*+json?

@alefranz commented on GitHub (Oct 10, 2018): In the current version I believe sometimes you only have the body as bytes. Also matching a json with a string is often a pain as the sample response data for the mock are usually not minified, so in my scenario I still need the ability to change something in `DetectBodyTypeFromContentType` to be able to set custom media type as json. Ideally would be nice for that class to not be static and the library support to extend it but that seems quite a lot of work. What about using a regex and testing against `application/vnd\..*+json`?
Author
Owner

@StefH commented on GitHub (Oct 10, 2018):

The property DetectBodyTypeFromContentType is not really used in the logic, it's just for information.

The Content-Type is not used anymore in the logic now.

The real logic is done with the DetectedBodyType.

I can implement application/vnd\..*+json as a RegEx if you like, but the logic is not really used.

@StefH commented on GitHub (Oct 10, 2018): 1. The property `DetectBodyTypeFromContentType` is not really used in the logic, it's just for information. The **Content-Type** is not used anymore in the logic now. The real logic is done with the `DetectedBodyType`. 2. I can implement `application/vnd\..*+json` as a RegEx if you like, but the logic is not really used.
Author
Owner

@alefranz commented on GitHub (Oct 10, 2018):

Ok, I guess I didn't really get the gist of the PR. I'll have a better look. Do you publish the PR builds as prerelease on myget by any chance?

@alefranz commented on GitHub (Oct 10, 2018): Ok, I guess I didn't really get the gist of the PR. I'll have a better look. Do you publish the PR builds as prerelease on myget by any chance?
Author
Owner

@StefH commented on GitHub (Oct 10, 2018):

Added a preview version to MyGet
https://www.myget.org/F/wiremock-net/api/v3/index.json

@StefH commented on GitHub (Oct 10, 2018): Added a preview version to MyGet https://www.myget.org/F/wiremock-net/api/v3/index.json
Author
Owner

@lesnes commented on GitHub (Oct 11, 2018):

wow, that was quick. great job! looks like it would suit my purposes

@lesnes commented on GitHub (Oct 11, 2018): wow, that was quick. great job! looks like it would suit my purposes
Author
Owner

@StefH commented on GitHub (Oct 12, 2018):

@alefranz PR build is published at https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net / https://www.myget.org/F/wiremock-net/api/v3/index.json

Can you please test this one ?

@StefH commented on GitHub (Oct 12, 2018): @alefranz PR build is published at https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net / https://www.myget.org/F/wiremock-net/api/v3/index.json Can you please test this one ?
Author
Owner

@lesnes commented on GitHub (Oct 14, 2018):

i've tested my usage requirement for multipart/form-data against 1.0.4.18-ci-1343 and it is working now 👍

@lesnes commented on GitHub (Oct 14, 2018): i've tested my usage requirement for `multipart/form-data` against `1.0.4.18-ci-1343` and it is working now 👍
Author
Owner

@StefH commented on GitHub (Oct 14, 2018):

Good news.

@alefranz : If you can confirm this issue and also the other issue; I can create a new official build.

@StefH commented on GitHub (Oct 14, 2018): Good news. @alefranz : If you can confirm this issue and also the other issue; I can create a new official build.
Author
Owner

@alefranz commented on GitHub (Oct 14, 2018):

Apologies, I will be able to test only on Monday.

@alefranz commented on GitHub (Oct 14, 2018): Apologies, I will be able to test only on Monday.
Author
Owner

@alefranz commented on GitHub (Oct 15, 2018):

Nice, now the mapping has the body as json, however when I save the mappings with SaveStaticMappings I end up with all 3 versions of it (text, json and binary) in the json.
It would be nice to define which format to save in SaveStaticMappings

@alefranz commented on GitHub (Oct 15, 2018): Nice, now the mapping has the body as json, however when I save the mappings with `SaveStaticMappings` I end up with all 3 versions of it (text, json and binary) in the json. It would be nice to define which format to save in `SaveStaticMappings`
Author
Owner

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

Ah, I did not think of that.
By default, the mapping should only be saved for the DetectedBodyType, just as it is now. I'll fix this and a new version should be automatically added to MyGet once it's ready.

Saving all 3 would be an additional option, which will be available in the next version.

@StefH commented on GitHub (Oct 15, 2018): Ah, I did not think of that. By default, the mapping should only be saved for the `DetectedBodyType`, just as it is now. I'll fix this and a new version should be automatically added to MyGet once it's ready. Saving all 3 would be an additional option, which will be available in the next version.
Author
Owner

@alefranz commented on GitHub (Oct 15, 2018):

but in my scenario with application/vnd.*+json what would be the DetectedBodyType?

@alefranz commented on GitHub (Oct 15, 2018): but in my scenario with `application/vnd.*+json` what would be the DetectedBodyType?
Author
Owner

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

@alefranz
When I think about it again...

1]
The DetectBodyType will be be based on the body, not on content-type.

2]
The DetectBodyTypeFromContentType will be be based on the content-type, but it's not used in the logic.

3]
I think you mean /__admin/requests or RequestsGet() ? That code does indeed save all 3 versions:

"Body": "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }",
"BodyAsJson": {
	"things": [
		{
			"name": "RequiredThing"
		},
		{
			"name": "Wiremock"
		}
	]
},
"BodyAsBytes": "eyAidGhpbmdzIjogWyB7ICJuYW1lIjogIlJlcXVpcmVkVGhpbmciIH0sIHsgIm5hbWUiOiAiV2lyZW1vY2siIH0gXSB9",

This I can update.

@StefH commented on GitHub (Oct 15, 2018): @alefranz When I think about it again... 1] The `DetectBodyType` will be be based on the body, not on content-type. 2] The `DetectBodyTypeFromContentType` will be be based on the content-type, but it's not used in the logic. 3] I think you mean `/__admin/requests` or `RequestsGet()` ? That code does indeed save all 3 versions: ``` js "Body": "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }", "BodyAsJson": { "things": [ { "name": "RequiredThing" }, { "name": "Wiremock" } ] }, "BodyAsBytes": "eyAidGhpbmdzIjogWyB7ICJuYW1lIjogIlJlcXVpcmVkVGhpbmciIH0sIHsgIm5hbWUiOiAiV2lyZW1vY2siIH0gXSB9", ``` This I can update.
Author
Owner

@alefranz commented on GitHub (Oct 15, 2018):

This is my workflow:

  • I start the mock as proxy
ProxyAndRecordSettings = new ProxyAndRecordSettings
                {
                    Url = originaUrl,
                    SaveMapping = true,
                    SaveMappingToFile = false
                };
  • I execute my end to end flow
  • on shutdown I use SaveStaticMappings to save the generated mapping (which contains the proxied response) to a specific folder (as with SaveMappingToFile I can't specify a folder, but I have multiple mocks running so I need to separate those)

All this responses are json but I have custom media types application/vnd.*+json.

The purpose of this is to automatically generate the mappings to load in my tests.

My goal is to have only BodyAsJson in the saved mapping as it is the readable one.

@alefranz commented on GitHub (Oct 15, 2018): This is my workflow: - I start the mock as proxy ``` c# ProxyAndRecordSettings = new ProxyAndRecordSettings { Url = originaUrl, SaveMapping = true, SaveMappingToFile = false }; ``` - I execute my end to end flow - on shutdown I use `SaveStaticMappings` to save the generated mapping (which contains the proxied response) to a specific folder (as with `SaveMappingToFile` I can't specify a folder, but I have multiple mocks running so I need to separate those) All this responses are json but I have custom media types `application/vnd.*+json`. The purpose of this is to automatically generate the mappings to load in my tests. My goal is to have only `BodyAsJson` in the saved mapping as it is the readable one.
Author
Owner

@StefH commented on GitHub (Oct 16, 2018):

I see your point.
Can you try latest from the MyGet feed: 1.0.4.18-ci-1349 ?

See https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions for details on MyGet

@StefH commented on GitHub (Oct 16, 2018): I see your point. Can you try latest from the MyGet feed: 1.0.4.18-ci-1349 ? See https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions for details on MyGet
Author
Owner

@StefH commented on GitHub (Oct 23, 2018):

@alefranz : did you have time to test the latest version on MyGet?

@StefH commented on GitHub (Oct 23, 2018): @alefranz : did you have time to test the latest version on MyGet?
Author
Owner

@alefranz commented on GitHub (Oct 24, 2018):

Apologies for the delay.

It works like a charm!

Thanks!

@alefranz commented on GitHub (Oct 24, 2018): Apologies for the delay. It works like a charm! Thanks!
Author
Owner

@StefH commented on GitHub (Oct 24, 2018):

@alefranz Are you sure you tested the 1.0.4.18-ci-1349 (or later) MyGet version ?

@StefH commented on GitHub (Oct 24, 2018): @alefranz Are you sure you tested the 1.0.4.18-ci-1349 (or later) MyGet version ?
Author
Owner

@alefranz commented on GitHub (Oct 25, 2018):

Yes, I've tested 1.0.4.18-ci-1349 and the saved mapping contains only the BodyAsJson as desired

@alefranz commented on GitHub (Oct 25, 2018): Yes, I've tested 1.0.4.18-ci-1349 and the saved mapping contains only the BodyAsJson as desired
Author
Owner

@alefranz commented on GitHub (Oct 26, 2018):

Thank you!

@alefranz commented on GitHub (Oct 26, 2018): Thank you!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#145