Question : Extracting text from a request.body that is not json #142

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

Originally created by @fransjvanderlinde on GitHub (Sep 6, 2018).

Hi is there any way to use the transformers to pull text from a requestbody by passing in a regex expression and using that value in response body. At moment it looks like code only caters for json to get info from a json node.

Originally created by @fransjvanderlinde on GitHub (Sep 6, 2018). Hi is there any way to use the transformers to pull text from a requestbody by passing in a regex expression and using that value in response body. At moment it looks like code only caters for json to get info from a json node.
adam closed this issue 2025-12-29 14:23:29 +01:00
Author
Owner

@StefH commented on GitHub (Sep 6, 2018):

Correct.
Currently it's only possible to use all functionality from Handlebars on a text string or on a json object.

Using RegEx (on a string), XPath (on a string) or Linq (on a json object) is not yet supported. I'm working on the last now.

@StefH commented on GitHub (Sep 6, 2018): Correct. Currently it's only possible to use all functionality from Handlebars on a text string or on a json object. Using RegEx (on a string), XPath (on a string) or Linq (on a json object) is not yet supported. I'm working on the last now.
Author
Owner

@StefH commented on GitHub (Sep 7, 2018):

Hello @fransjvanderlinde, I could implement logic for

  • RegEx
  • XPath
  • DynamicLinq

on the request body (string) using extensions on HandleBars, just like I did for https://github.com/WireMock-Net/WireMock.Net/wiki/Response-Templating#jsonpathselecttoken

So an example mapping for Regex.Match could be:

{
    "Request": {
        "Path": {
            "Matchers": [
                {
                    "Name": "WildcardMatcher",
                    "Pattern": "/regex"
                }
            ]
        },
        "Methods": [
            "post"
        ]
    },
    "Response": {
        "Body": "{{Regex.Match request.body \"...Regex to match something here...\"}}",
        "UseTransformer": true
    }
}

Would this idea be what you need?

@StefH commented on GitHub (Sep 7, 2018): Hello @fransjvanderlinde, I could implement logic for * RegEx * XPath * DynamicLinq on the request body (string) using extensions on **HandleBars**, just like I did for https://github.com/WireMock-Net/WireMock.Net/wiki/Response-Templating#jsonpathselecttoken So an example mapping for `Regex.Match` could be: ``` js { "Request": { "Path": { "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "/regex" } ] }, "Methods": [ "post" ] }, "Response": { "Body": "{{Regex.Match request.body \"...Regex to match something here...\"}}", "UseTransformer": true } } ``` Would this idea be what you need?
Author
Owner

@fransjvanderlinde commented on GitHub (Sep 7, 2018):

Yes that sounds like it will work. I did something like below in my app which did give me the values but i would like to do a lot more complex regex so solution suggested will work much better.

Handlebars.RegisterHelper("extractamount", (output, context, arguments) =>
{
  var match = Regex.Match((string) arguments[0], @"\d +.+\d");

  if (match.Success)
  {
    output.WriteSafeString(match.Value);
   }
   else
   {
     output.WriteSafeString("0");
    }
}

 server
.Given(Request
.Create()
.WithPath("/test")
.UsingPost())
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithHeader("Content-Type", "application/text")
.WithTransformer().WithBody(@"{{extractvalue request.body}}")
@fransjvanderlinde commented on GitHub (Sep 7, 2018): Yes that sounds like it will work. I did something like below in my app which did give me the values but i would like to do a lot more complex regex so solution suggested will work much better. ``` c# Handlebars.RegisterHelper("extractamount", (output, context, arguments) => { var match = Regex.Match((string) arguments[0], @"\d +.+\d"); if (match.Success) { output.WriteSafeString(match.Value); } else { output.WriteSafeString("0"); } } server .Given(Request .Create() .WithPath("/test") .UsingPost()) .RespondWith(Response.Create() .WithStatusCode(200) .WithHeader("Content-Type", "application/text") .WithTransformer().WithBody(@"{{extractvalue request.body}}") ```
Author
Owner

@StefH commented on GitHub (Sep 7, 2018):

Hi @fransjvanderlinde,

I've update the code to support this logic:

Regex.Matches

// Assign
var body = new BodyData { BodyAsString = "https://localhost:5000/" };

var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);

var response = Response.Create()
    .WithBody("{{#Regex.Matches request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{this.port}}-{{this.proto}}{{/Regex.Matches}}")
    .WithTransformer();

// Act
var responseMessage = await response.ProvideResponseAsync(request);

// assert
Check.That(responseMessage.Body).Equals("5000-https");

Regex.Match

// Assign
var body = new BodyData { BodyAsString = "abc" };

var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);

var response = Response.Create()
    .WithBody("{{Regex.Match request.body \"^(?<x>\\w+)$\"}}")
    .WithTransformer();

// Act
var responseMessage = await response.ProvideResponseAsync(request);

// assert
Check.That(responseMessage.Body).Equals("abc");

Would this be as you would use it?

@StefH commented on GitHub (Sep 7, 2018): Hi @fransjvanderlinde, I've update the code to support this logic: **Regex.Matches** ``` c# // Assign var body = new BodyData { BodyAsString = "https://localhost:5000/" }; var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body); var response = Response.Create() .WithBody("{{#Regex.Matches request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{this.port}}-{{this.proto}}{{/Regex.Matches}}") .WithTransformer(); // Act var responseMessage = await response.ProvideResponseAsync(request); // assert Check.That(responseMessage.Body).Equals("5000-https"); ``` **Regex.Match** ```c# // Assign var body = new BodyData { BodyAsString = "abc" }; var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body); var response = Response.Create() .WithBody("{{Regex.Match request.body \"^(?<x>\\w+)$\"}}") .WithTransformer(); // Act var responseMessage = await response.ProvideResponseAsync(request); // assert Check.That(responseMessage.Body).Equals("abc"); ``` Would this be as you would use it?
Author
Owner

@StefH commented on GitHub (Sep 8, 2018):

Or maybe better to keep the name Regex.Match for both?

@StefH commented on GitHub (Sep 8, 2018): Or maybe better to keep the name `Regex.Match` for both?
Author
Owner

@fransjvanderlinde commented on GitHub (Sep 11, 2018):

Looks good. Thanks

@fransjvanderlinde commented on GitHub (Sep 11, 2018): Looks good. Thanks
Author
Owner

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

I'll create PR and new NuGet.

@StefH commented on GitHub (Sep 11, 2018): I'll create PR and new NuGet.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#142