-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Closed
Closed
Copy link
Description
Symfony version(s) affected
6.4.6
Description
It seems to be impossible to validate request properly when sent empty. For both query string and request payload mapper will return null
and skip validation. Using default value makes callable being called with object which may be invalid.
How to reproduce
final class ApiDTO
{
#[Assert\NotBlank]
public string $foo = '';
}
class FooController extends AbstractController
{
#[Route("/foo", methods: ["GET"])]
public function __invoke(#[MapQueryString(validationFailedStatusCode: 400)] ApiDTO $dto = new ApiDTO()): JsonResponse {
dd($dto);
}
}
expected behavior
GET /foo?foo= -> 400
validation skipped
GET /foo -> ApiDTO {
+foo: ""
}
Possible Solution
Possible solution would be to make mapper method return default value if defined instead of returning null
// symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php:162
private function mapQueryString(Request $request, string $type, MapQueryString $attribute): ?object
{
if (!$data = $request->query->all()) {
return $attribute->metadata->hasDefaultValue() ? $attribute->metadata->getDefaultValue() : null;
}
return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE);
}
// symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php:185
if ('' === $data = $request->getContent()) {
return $attribute->metadata->hasDefaultValue() ? $attribute->metadata->getDefaultValue() : null;
}
GET /foo?foo= -> 400
GET /foo -> 400
Additional Context
No response
vracini, sztanpet, jlabedo and artyuum