Symfony 5 Rest,Base64 编码文件到 DTO,验证为文件对象
Symfony 5 Rest, Base64 encoded file to DTO with validation as File object
我有一个 PostController
看起来像这样:
#[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);
}
和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;
}
我的 Postman 请求如下所示:
{
"title": "Test",
"article": "lorem ipsum....",
"photo": "base64...",
"publishDate": "2021-10-15 08:00:00"
}
正如您从邮递员请求中看到的那样,我正在发送 base64
编码文件。
现在,在控制器中,我想将其反序列化以与 PostRequestDto
匹配,这样我就可以在 PostService
中将其验证为 File
- 我该如何实现?
我不知道你的序列化器 ($this->serializer
) 是如何配置的,但我认为你必须 adjust/add 你的规范化器 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);
如果您查看 DataUriNormalizer
内部,您会发现它与 File
一起使用,这正是您在 PostRequestDto
中所拥有的
唯一需要注意的是→base64格式。
如果你遵循 denormilize()
方法的 link,你会看到它期望 data:image/png;base64,...
所以它必须以 data:...
开头,您可能必须将邮递员-json-payload 更改为
{
"title": "Test",
"article": "lorem ipsum....",
"photo": "data:<your_base64_string>",
"publishDate": "2021-10-15 08:00:00"
}
由于您使用的是图像,所以我也会发送 mime 类型。喜欢:
"photo": "data:image/png;base64,<your_base64_string>",
我有一个 PostController
看起来像这样:
#[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);
}
和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;
}
我的 Postman 请求如下所示:
{
"title": "Test",
"article": "lorem ipsum....",
"photo": "base64...",
"publishDate": "2021-10-15 08:00:00"
}
正如您从邮递员请求中看到的那样,我正在发送 base64
编码文件。
现在,在控制器中,我想将其反序列化以与 PostRequestDto
匹配,这样我就可以在 PostService
中将其验证为 File
- 我该如何实现?
我不知道你的序列化器 ($this->serializer
) 是如何配置的,但我认为你必须 adjust/add 你的规范化器 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);
如果您查看 DataUriNormalizer
内部,您会发现它与 File
一起使用,这正是您在 PostRequestDto
唯一需要注意的是→base64格式。
如果你遵循 denormilize()
方法的 link,你会看到它期望 data:image/png;base64,...
所以它必须以 data:...
开头,您可能必须将邮递员-json-payload 更改为
{
"title": "Test",
"article": "lorem ipsum....",
"photo": "data:<your_base64_string>",
"publishDate": "2021-10-15 08:00:00"
}
由于您使用的是图像,所以我也会发送 mime 类型。喜欢:
"photo": "data:image/png;base64,<your_base64_string>",