I have a PostController
looking like this:
#[Route(name: 'add', methods: ['POST'])]
public function addPost(Request $request): JsonResponse
{
/** @var PostRequestDto $postRequest */
$postRequest = $this->serializer->deserialize(
$request->getContent(),
PostRequestDto::class,
'json'
);
return $this->postService->addPost($postRequest);
}
PostService
:
public function addPost(PostRequestDto $request): JsonResponse
{
$errors = $this->validator->validate($request);
if (count($errors) > 0) {
throw new ValidationHttpException($errors);
}
#...
return new JsonResponse(null, Response::HTTP_CREATED);
}
And PostRequestDto
:
class PostRequestDto
{
#[Assert\NotBlank]
#[Assert\Length(max: 250)]
private ?string $title;
#[Assert\NotBlank]
#[Assert\Length(max: 1000)]
private ?string $article;
#[Assert\NotBlank]
#[Assert\Image]
private ?File $photo;
#[Assert\NotBlank]
#[Assert\GreaterThanOrEqual('now', message: 'post_request_dto.publish_date.greater_than_or_equal')]
private ?DateTimeInterface $publishDate;
}
My Postman request looks like this:
{
"title": "Test",
"article": "lorem ipsum....",
"photo": "base64...",
"publishDate": "2021-10-15 08:00:00"
}
As you can see from postman request, I'm sending base64
encoded file.
Now, in the controller I want to deserialize it to match with PostRequestDto
so I can validate it as a File
in the PostService
- how can I achieve this ?
CodePudding user response:
I don't know how exactly your serializer ($this->serializer
) is configured, but I think you have to adjust/add your normilizer with Symfony\Component\Serializer\Normalizer\DataUriNormalizer
// somewhere in your controller/service where serilaizer is configured/set
$normalizers = [
//... your other normilizers if any
new DataUriNormalizer(), // this one
];
$encoders = [new JsonEncoder()];
$this->serializer = new Serializer($normalizers, $encoders);
If you look inside DataUriNormalizer
you'll see, it works with File
which is exactly what you have in your PostRequestDto
The only thing to be aware of → format of base64.
If you follow the link of denormilize()
method, you will see it expects data:image/png;base64,...
So it has to start with data:...
and you probably have to change your postman-json-payload to
{
"title": "Test",
"article": "lorem ipsum....",
"photo": "data:<your_base64_string>",
"publishDate": "2021-10-15 08:00:00"
}
Since you work with images, I would also send the mime-type. Like:
"photo": "data:image/png;base64,<your_base64_string>",