验证 symfony 表单以提交 POST 请求时出现问题

Probleme validating a symfony form to submit POST request

我正在开发 POST REST 服务以创建新的 "User"。

我按照这个教程,它是法语的,但我使用的代码应该是一样的。

https://zestedesavoir.com/tutoriels/1280/creez-une-api-rest-avec-symfony-3/developpement-de-lapi-rest/creer-et-supprimer-des-ressources/

因此,当我尝试使用 post 休息服务添加用户时,它成功了。 当我添加表单验证来验证我的请求的参数时,每个字段 return 一个错误 "This value should not be blank.",但我发送了正确的值

错误 returned 使用 Postman :

{
  "code": 400,
  "message": "Validation Failed",
  "errors": {
    "errors": [
      "This form should not contain extra fields."
    ],
    "children": {
      "firstname": {
        "errors": [
          "This value should not be blank."
        ]
      },
      "lastname": {
        "errors": [
          "This value should not be blank."
        ]
      },
      "email": {
        "errors": [
          "This value should not be blank."
        ]
      }
    }
  }
}

我使用 PostMan 发送此代码:

{
    "firstname": "Jimmy",
    "lastname": "Sample",
    "email": "mail@domain.com"
}

当我尝试打印 $form->submit($request->request->all()); 时,我得到一个空数组,所以我想这就是问题所在。 请参阅用户控制器代码。

查看我使用的代码:

用户

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity()
* @ORM\Table(name="users",
*      uniqueConstraints={@ORM\UniqueConstraint(name="users_email_unique",columns={"email"})}
* )
*/
class User
{
   /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $firstname;

    /**
     * @ORM\Column(type="string")
     */
    protected $lastname;

    /**
     * @ORM\Column(type="string")
     */
    protected $email;

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function getFirstname()
    {
        return $this->firstname;
    }

    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;
    }

    public function getLastname()
    {
        return $this->lastname;
    }

    public function setLastname($lastname)
    {
        $this->lastname = $lastname;
    }

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

用户控制器

<?php
namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\Annotations as Rest; // alias pour toutes les annotations
use AppBundle\Form\Type\UserType;
use AppBundle\Entity\User;

class UserController extends Controller
{
[...]
    /**
     * @Rest\View(statusCode=Response::HTTP_CREATED)
     * @Rest\Post("/users")
     */
    public function postUsersAction(Request $request)
    {
        $user = new User();
        $form = $this->createForm(UserType::class, $user);

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

        if ($form->isValid()) {
            $em = $this->get('doctrine.orm.entity_manager');
            $em->persist($user);
            $em->flush();
            return $user;
        } else {
            return $form;
        }
    }
}

用户类型(表格类型)

<?php
namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('firstname')
            ->add('lastname')
            ->add('email', EmailType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\User',
            'csrf_protection' => false
        ]);
    }
}

验证 YML 文件

AppBundle\Entity\User:
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: email
    properties:
        firstname:
            - NotBlank: {message: Noooooon il faut un prénom!!!}
            - Type: string
        lastname:
            - NotBlank: ~
            - Type: string
        email:
            - NotBlank: ~
            - Email: ~

谢谢

您正在发送 json,然后需要解码 json

    $json = $request->getContent();
    if ($decodedJson = json_decode($json, true)) {
        $data = $decodedJson;
    } else {
        $data = $request->request->all();
    }
    $formData = [];
    foreach ($form->all() as $name => $field) {
        if (isset($data[$name])) {
            $formData[$name] = $data[$name];
        }
    }

    $form->submit($formData);

您还可以在 fos_rest:

中启用 body_listener 选项
fos_rest:
    body_listener: true

然后:

$request->request->all();

将包含来自 json、xml...

的解码数据

有关 body_listener 选项的更多信息,请阅读下一篇文章:http://symfony.com/doc/master/bundles/FOSRestBundle/body_listener.html