symfony4 - form->isValid() return false 和 form->getErrors return 空数组

symfony4 - form->isValid() return false and form->getErrors return empty array

我使用带有 FOSRestBundle 的 symfony 4。 我有控制器:

/**
 * @Route("/api")
 */
class ProjectController extends FOSRestController
{
    /**
     * @FOSRest\Post("/project")
     */
    public function postProjectAction(Request $request, ValidatorInterface $validator)
    {
        $project = new Project();

        $project->setCreatedBy($this->getUser()->getUser());

        $project->setCreatedAt(new \DateTime());

        $form = $this->createForm(ProjectType::class, $project);

        $form->submit($request->request->all());

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($project);
            $em->flush();
            return new JsonResponse([
                'status' => 'created'
            ], 200);
        }
        return new JsonResponse($form->getErrors(true, false), 400);
    }

}

当我转储 $form->isValid() 时,我得到了 false,但响应正文是 []

我如何得到字段错误?或者我做错了什么?

有项目类型:

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class,
                [
                    'label' => 'label.name'
                ]
            )
            ->add('nameKey', TextType::class,
                [
                    'label' => 'label.nameKey'
                ]
            )
            ->add('description', TextareaType::class,
                [
                    'label' => 'label.description'
                ]
            )
            ->add('deadline', DateTimeType::class,
                [
                    'label' => 'label.deadline',
                    'widget' => 'single_text',
                    'html5' => false,
                    'attr' => [
                        'class' => 'bootstrap-datetimepicker'
                    ],
                    'format' => 'yyyy-mm-dd HH:ii'
                ]
            )
            ->add('active', ChoiceType::class,
                [
                    'label' => 'label.active',
                    'choices' => [
                        'label.yes' => true,
                        'label.no' => false
                    ]
                ]
            )
            ->add('priority', EntityType::class,
                [
                    'class' => Priority::class,
                    'choice_label' => 'name',
                    'label' => 'label.priority',
                ]
            )
            ->add('assignedUsers', EntityType::class, 
                [
                    'class' => User::class,
                    'choice_label' => 'email',
                    'label' => 'label.',
                    'multiple' => true,
                ]
            )
            ->add('assignedCustomers', EntityType::class, 
                [
                    'class' => Customer::class,
                    'choice_label' => 'email',
                    'label' => 'label.',
                ]
            )
        ;

        $builder->get('priority')->addModelTransformer($this->priorityToNumberTransformer);
        $builder->get('assignedUsers')->addModelTransformer($this->userToNumberTransformer);
        $builder->get('assignedCustomers')->addModelTransformer($this->customerToNumberTransformer);
    }

并请求我发送的数据:

{ "name": "asd", "nameKey": "AS", "description": "Simple desc", "priority": "1", "deadline": "2016-09-01 21:02:20", "active": true, "assignedCustomers": {}, "assignedUsers": {} }

很可能是您遇到了 CSRF 保护方面的问题。尝试创建表单并禁用 CSRF 保护。 在无状态 API 上进行 CSRF 保护是非常无用的,但默认情况下启用。

您可以在创建表单时禁用它:

$form = $this->createForm(ProjectType::class, $project, [
    'csrf_protection' => false,
]);

或者您通过配置禁用它,通过定义用户角色:

fos_rest:
    disable_csrf_role: ROLE_API

https://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#csrf-validation

当您遇到表单验证错误时,您应该return换个角度看。根据文档 https://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#forms-and-views 这可能是这样的:

return new View($form, Response::HTTP_BAD_REQUEST);