2

why I get 400 bad request when testing ASP.NET CORE minimal API app with Postman?

Default VS 2022 ASP.NET core minimal API project, with following method handler:

app.MapPost("/test", (AnalizeSentenceRequest r) =>
{
    return Results.Ok($"Echo: {r.Sentence}");
});

DTO:

public class AnalizeSentenceRequest
{
    public string? Sentence { get; set; }
}

Windows 10 or Ubuntu curls works fine:

> curl -X POST http://localhost:5050/test -H "Content-Type: application/json" -d "{\"sentence\":\"testing\"}"

response:

"Echo: testing"

But Postman gets 400:

enter image description here

Postman headers:

enter image description here

Edit: Postman response:

It complains that it cannot bind to DTO AnalizeSentenceRequest r

I tried to add [FromBody] attribute to the handler:

([FromBody] AnalizeSentenceRequest r) => ...

but it makes no difference.

It works with curl though... So it looks like Postman is messing up with the body, but what it might be?

Full response:

Microsoft.AspNetCore.Http.BadHttpRequestException: Required parameter "AnalizeSentenceRequest r" was not provided from body.
   at Microsoft.AspNetCore.Http.RequestDelegateFactory.Log.RequiredParameterNotProvided(HttpContext httpContext, String parameterTypeName, String parameterName, String source, Boolean shouldThrow)
   at lambda_method1(Closure , Object , HttpContext , Object )
   at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass46_3.<<HandleRequestBodyAndCompileRequestDelegate>b__2>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Host: localhost:5050
Content-Type: application/json
zizu_zaza
  • 95
  • 1
  • 8
  • what is the content of the 400 response? – Roman Marusyk Jan 12 '22 at 12:07
  • @RomanMarusyk - thanks for looking into this! I edited OP and provided Postman's response. – zizu_zaza Jan 12 '22 at 12:23
  • Try sending this json: {"r": {"sentence": "sometext"} } – AchoVasilev Jan 12 '22 at 12:26
  • @AchoVasilev - no idea how ASP.NET Core binding would handle this, but I did it and result is different now for postman, but still 400 "Implicit body inferred for parameter "r" but no body was provided. Did you mean to use a Service instead?" but curl works just fine and returns according to handler method body... Edit: corrected Postman 400 response, it's different now. – zizu_zaza Jan 12 '22 at 12:29
  • It looks like Postman encodes body in such a way that it's dropping out of asp.net core pipeline - is there any way how I catch request contents before it goes downstream to the pipeline? – zizu_zaza Jan 12 '22 at 12:34
  • @zizu_zaza try putting a check in the Content-Length checkbox in postman – AchoVasilev Jan 12 '22 at 12:41
  • 1
    @zizu_zaza The Content-Length header is mandatory for messages with entity bodies, unless the message is transported using chunked encoding. Content-Length is needed to detect premature message truncation when servers crash and to properly segment messages that share a persistent connection. – AchoVasilev Jan 12 '22 at 12:49
  • @AchoVasilev - content-length header fixed this! Thanks! If you care to add this as an answer I'd mark it. – zizu_zaza Jan 12 '22 at 13:24
  • @zizu_zaza did it. I am glad it helped! – AchoVasilev Jan 12 '22 at 13:25

1 Answers1

3

Putting a check in the Content-Length checkbox in Postman. Reason being is that the Content-Length header is mandatory for messages with entity bodies, unless the message is transported using chunked encoding. Content-Length is needed to detect premature message truncation when servers crash and to properly segment messages that share a persistent connection.

AchoVasilev
  • 454
  • 5
  • 15