使用Symfony 3和FOSrestBundle验证表单

时间:2017-11-07 18:30:13

标签: php symfony fosrestbundle

我正在根据FOSrestBundle制作一些关于制作一些REST API的教程,但我遇到了关于表单验证的问题。

我尝试在该端点使用POST请求在我的数据库中添加新用户: http://127.0.0.1:8000/users

但它只返回一个不应该为空的值的错误。

我的类UserController有这个方法:

/**
 * @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"user"})
 * @Rest\Post("/users")
 */
public function postUsersAction(Request $request)
{
    $user = new User();
    $form = $this->createForm(UserType::class, $user, ['validation_groups'=>['Default', 'New']]);

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

    if ($form->isValid()) {
        $encoder = $this->get('security.password_encoder');
        $encoded = $encoder->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($encoded);

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

我的validation.yml:

AppBundle\Entity\User:
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: email
    properties:
        firstname:
            - NotBlank: ~
            - Type: string
        lastname:
            - NotBlank: ~
            - Type: string
        email:
            - NotBlank: ~
            - Email: ~
        plainPassword:
            - NotBlank: { groups: [New, FullUpdate] }
            - Type: string
            - Length:
                min: 4
                max: 50

这是我的实体用户:

/**
* @ORM\Entity()
* @ORM\Table(name="users",
*      uniqueConstraints={@ORM\UniqueConstraint(name="users_email_unique",columns={"email"})}
* )
*/
class User implements UserInterface
{
   /**
     * @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;

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

    protected $plainPassword;

    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;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function setPassword($password)
    {
        $this->password = $password;
    }

    public function getPlainpassword()
    {
        return $this->plainPassword;
    }

    public function getRoles()
    {
        return [];
    }

    public function getSalt()
    {
        return null;
    }

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

    public function eraseCredentials()
    {
        // Suppression des données sensibles
        $this->plainPassword = null;
    }
}

在UserType.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');
        $builder->add('lastname');
        $builder->add('plainPassword');
        $builder->add('email', EmailType::class);
    }

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

我使用Postman发送我的POST请求,并使用该有效负载:

{
    "firstname": "foo",
    "lastname": "bar",
    "email": "test@test.com",
    "password": "qwerty"
}

但我收到400错误:

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

编辑1

如果我在validation.yml中用密码替换plainPassword,那么该错误将返回:

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

如果您需要查看其他文件,请告诉我。

无论如何,谢谢你的帮助!

分辨

所以@ kunicmarko20谢天谢地帮助了我,我在POST请求发送的有效负载中出错,这里是正确的:

{
    "firstname": "foo",
    "lastname": "bar",
    "email": "test@test.com",
    "plainPassword": "qwerty"
}

最重要的是,我完全忘了在我的用户实体中放置一个setter,我们走了:

public function getPlainPassword()
{
    return $this->plainPassword;
}

public function setPlainPassword($plainpassword)
{
    $this->plainPassword = $plainpassword;
}

1 个答案:

答案 0 :(得分:0)

如果您要使用$form->submit(),那么传递给它的值应该是一个数组,它看起来像:

$data = json_decode($request->getContent(), true);
$form->submit($data);

完全相同的东西,它没有问题。

编辑:

我刚看了一眼,你正在定义plainPassword并在你的json中发送password,试试这样:

{
    "firstname": "foo",
    "lastname": "bar",
    "email": "test@test.com",
    "plainPassword": "qwerty"
}