mezzio / mezzio-helpers

Helper/Utility classes for Mezzio
https://docs.mezzio.dev/mezzio/features/helpers/intro/
BSD 3-Clause "New" or "Revised" License
12 stars 13 forks source link

BodyParamsMiddleware: Valid JSON containing a scalar value causes InvalidArgumentException #1

Closed weierophinney closed 1 year ago

weierophinney commented 4 years ago

If the request body contains a valid scalar JSON value e.g. string, boolean or int, an InvalidArgumentException is thrown.

Code to reproduce the issue

Using BodyParamsMiddleware with the standard JsonStartegy.

Like described here: https://docs.zendframework.com/zend-expressive/v3/features/helpers/body-parse/

Send a request with the Content-Type header 'application/json' and the body containing any of this:

Expected results

Expecting to use \Psr\Http\Message\ServerRequestInterface::getParsedBody().

Actual results

InvalidArgumentException
Zend\Diactoros\ServerRequest::withParsedBody expects a null, array, or object argument; received integer

Originally posted by @MrKey at https://github.com/zendframework/zend-expressive-helpers/issues/67

weierophinney commented 4 years ago

@MrKey Can you create a test case? I can't reproduce it here.


Originally posted by @geerteltink at https://github.com/zendframework/zend-expressive-helpers/issues/67#issuecomment-427035225

weierophinney commented 4 years ago

Steps to reproduce: 1) Create the default zend skeleton app like described here: https://docs.zendframework.com/zend-expressive/v3/getting-started/quick-start/ 1.1) all defaults 1.2) run webserver 2) Modify config/routes.php to add a POST route along the two default get routes:

return function (Application $app, MiddlewareFactory $factory, ContainerInterface $container) : void {
    $app->get('/', App\Handler\HomePageHandler::class, 'home');
    $app->post('/', [Zend\Expressive\Helper\BodyParams\BodyParamsMiddleware::class, App\Handler\HomePageHandler::class]);
    $app->get('/api/ping', App\Handler\PingHandler::class, 'api.ping');
};

3) Make a request with the 'Content-Type: application/json' header and with the body '2' (without any braces):

POST  HTTP/1.1
Host: localhost:8080
Content-Type: application/json

2

Result:

Zend\Diactoros\Exception\InvalidArgumentException: Zend\Diactoros\ServerRequest::withParsedBody expects a null, array, or object argument; received integer in file ...

Originally posted by @MrKey at https://github.com/zendframework/zend-expressive-helpers/issues/67#issuecomment-427044408

weierophinney commented 4 years ago

Shouldn't you pass valid json? Let me rephrase that...

It is valid json I guess. But as the Exception message says, it expects that json_decode returns null, array or object. json_decode(2, true) returns an integer as the exception tells you.

To have json_decode return something useful, you need to feed it something that translates to an array: {"data":2}.


Originally posted by @geerteltink at https://github.com/zendframework/zend-expressive-helpers/issues/67#issuecomment-427068253

psfpro commented 3 years ago

I got a similar error with the data

"{\"a\":123}"

result will be

Laminas\Diactoros\Exception\InvalidArgumentException: Laminas\Diactoros\ServerRequest::withParsedBody expects a null, array, or object argument; received string in file /app/vendor/laminas/laminas-diactoros/src/ServerRequest.php on line 186

What solution can there be?