Symfony:如何使用 MapRequestPayload 将 JSON 对象数组映射到 DTO 数组

问题描述 投票:0回答:1

我正在使用 Symfony 并有一个传入的 JSON 负载,如下所示:

[
    {
        "number": 1,
        "description": "Test 1"
    },
    {
        "number": 2,
        "description": "Test 2"
    },
   {
        "number": 3,
        "description": "Test 3"
    }
]

我有一个数据传输对象(DTO)定义如下:

<?php

class MyDto {

 public function __constructor(
   public readonly int $number,
   public readonly int $description,
 ) {}
}

我的目标是将 JSON 对象数组直接映射到 Symfony 控制器中的 MyDto 对象数组。这是我当前的控制器方法:

public funtion index(#[MapRequestPayload] MyDto $dto) {
    ...
}

我正在尝试找到一种方法将 JSON 对象数组映射到 MyDto 对象数组,而不需要创建另一个 DTO 来将此数据包装在键下。 Symfony 中是否有内置或有效的方法来执行此操作?

php symfony
1个回答
0
投票

要将 JSON 对象数组直接映射到 Symfony 中的

MyDto
对象数组,您可以使用 Symfony Serializer 组件。但是,您的控制器方法需要稍微调整,因为 Symfony 不会自动将 JSON 对象数组映射到开箱即用的 DTO 数组。

以下是实现此目标的方法:

1。确保正确的 DTO 构造函数:

首先,您的 MyDto 构造函数中有一个小拼写错误。应该是

__construct
,而不是
__constructor
:

<?php

class MyDto {

    public function __construct(
        public readonly int $number,
        public readonly string $description,
    ) {}
}

2。在控制器中使用 Symfony 序列化器:

您可以使用控制器中的

Serializer
服务将 JSON 负载反序列化为
MyDto
对象数组。

您的控制器方法可能如下所示:

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\SerializerInterface;

class MyController extends AbstractController
{
    public function index(Request $request, SerializerInterface $serializer): JsonResponse
    {
        $jsonContent = $request->getContent();

        /** @var MyDto[] $dtos */
        $dtos = $serializer->deserialize($jsonContent, 'App\Dto\MyDto[]', 'json');

        // Do something with the $dtos array
        foreach ($dtos as $dto) {
            // Your logic here
        }

        return new JsonResponse(['status' => 'success']);
    }
}

验证示例:

use Symfony\Component\Validator\Validator\ValidatorInterface;

public function index(Request $request, SerializerInterface $serializer, ValidatorInterface $validator): JsonResponse
{
    $jsonContent = $request->getContent();

    /** @var MyDto[] $dtos */
    $dtos = $serializer->deserialize($jsonContent, 'App\Dto\MyDto[]', 'json');

    foreach ($dtos as $dto) {
        $errors = $validator->validate($dto);
        if (count($errors) > 0) {
            // Handle validation errors (return response, throw exception, etc.)
        }
    }

    // Proceed with your logic

    return new JsonResponse(['status' => 'success']);
}
© www.soinside.com 2019 - 2024. All rights reserved.