【发布时间】:2020-06-10 02:17:29
【问题描述】:
我有一个带有嵌套 PointDto 类(点数组)的 OrderDto 类:
class OrderDto
{
/**
* @var PointDto[]
* @Assert\All({
* @Assert\Type("App\Dto\PointDto")
* })
* @Assert\Valid()
*/
private array $points;
// getters, setters
}
PointDto 类也使用验证器约束:
class PointDto
{
/**
* @Assert\NotBlank()
*/
private string $address;
// getters, setters
}
我的控制器:
/**
* @Rest\Post("/order/calc")
* @ParamConverter("orderDto", converter="fos_rest.request_body")
*/
public function calcOrder(OrderDto $orderDto, ConstraintViolationListInterface $validationErrors)
{
if (count($validationErrors) > 0)
return $this->json($validationErrors, Response::HTTP_BAD_REQUEST);
return ApiResponseUtil::okData(['sum' => 0]);
}
但是什么时候发送带有嵌套 dto 对象的请求,像这样:
{
"points": [
{
"address": "",
"person": {
"name": "",
"phone": ""
}
}
]
}
验证器无法确定类型,错误:
{
"error": "points[0]: This value should be of type App\\Dto\\PointDto.",
"violations": [
{
"property": "points[0]",
"message": "This value should be of type App\\Dto\\PointDto."
}
]
}
有没有办法反序列化嵌套对象?
【问题讨论】:
-
您的问题似乎与 Symfony Serializer 如何解析您的点列表有关。当你使用
PointDto[]时它应该能够解决这个问题(就像你一样)。你能确定 ArrayDenormalizer 在serializer-service 中注册了吗?我认为最简单的找出方法是将 SerializerInterface 注入控制器,然后转储它。 -
@dbrumann,对于我在转储序列化程序服务中查看的冗长答案感到抱歉,它看起来像这样:^ Symfony\Component\Serializer\Serializer {#447 ▼ #encoder: Symfony\Component\Serializer\ Encoder\ChainEncoder {#425 ▶} #decoder: Symfony\Component\Serializer\Encoder\ChainDecoder {#376 ▶} #normalizers: array:15 [▼ 0 => App\Serializer\Normalizer\ConstraintViolationListNormalizer {#448} ... 13 => Symfony\Component\Serializer\Normalizer\ArrayDenormalizer {#428 ▼ -serializer: Symfony\Component\Serializer\Serializer {#447} } ... ]
-
看起来 ArrayDenormalizer 至少存在。那应该能够为您提供一组对象。我不知道有什么问题。一个最小的示例项目会有所帮助。我试着看看今天晚些时候能不能花一个小时研究一下。
-
我创建了一个带有测试用例的最小示例,它工作正常。两项测试均通过:gist.github.com/dbrumann/e379ef8c1511f3d36822cf14c3855857 您可以尝试删除 Validation-Constraints 并检查反序列化是否有效。也许这些注释与序列化程序推断类型的方式冲突。
-
我发现我的错误在缺席时出现:phpdocumentor/reflection-docblock 安装后一切正常
标签: symfony fosrestbundle symfony-validator