FOSRestBundle将json数据发布到不起作用的表单

时间:2015-03-16 00:56:58

标签: forms api symfony fosrestbundle

我将JSON数据发布到控制器中的表单。实体没有填写我发送的属性,这就是它的样子:

// Controller

class UserApiController extends FOSRestController
{
    // works fine
    public function cgetAction()
    {
        return $this->get('model.user')->getAllUsers();
    }

    // works fine
    public function getAction($id)
    {
        return $this->get('model.user')->getUserById($id);
    }

    // this method fails
    public function postAction(Request $request)
    {
        $form = $this->createForm(new UserType(), new User());
        $form->bind($request);

        if($form->isValid())
        {
            die('are you valid or not??');
        }

        return $this->view($form, 400);
    }
}

实体看起来像常规实体,也可以形成。

我有一个测试控制器,它将json数据发送到api:

public function testJsonPostAction()
    {
        $client = static::createClient();
        $client->request(
            'POST',
            '/api/1.0/users',
            array(),
            array(),
            array('CONTENT_TYPE' => 'application/json'),
            '{"firstName": "John", "lastName": "Doe", "emailAddress": "something@somewhere.com", "sex": "1"}'
        );

        var_dump($client->getResponse()->getContent());
    }

验证:

Software\Bundle\Entity\User:
    properties:
        firstName:
            - NotBlank: ~
            - Length:
                min: 2
                max: 255
        lastName:
            - NotBlank: ~
            - Length:
                min: 2
                max: 255

好的,问题是$ form始终无效。当我转储$ form-> getData()内容时,我得到了我的用户实体,但是没有填写firstName,lastName等。相反,我明显得到了验证错误,但这是另一个但是:

为什么$ form-> bind($ request)(我知道它已被弃用)返回这个(这更不好):

{"code":400,"message":"Validation Failed","errors":{"children":{"firstName":{"errors":["This value should not be blank."]},"lastName":{"errors":["This value should not be blank."]},"emailAddress":{"errors":["This value should not be blank."]},"sex
":[],"locale":[]}}}

和相同的代码,但使用$ form-> handleRequest($ request)返回:

{"children":{"firstName":[],"lastName":[],"emailAddress":[],"sex":[],"locale":[]}}

有什么区别?因为我认为handleRequest是bind的替代品。 我已经尝试过,我认为互联网上的所有解决方案都是不同的,我无法让它发挥作用。 FOSRestBundle的文档很差,它说的都是关于获取内容的,但几乎没有关于发布的内容。

任何帮助都非常感激。

2 个答案:

答案 0 :(得分:5)

由于没有人回复,我将在这个问题上回答自己。

首先,发送的JSON必须以表单名称开头,所以改为:

{"firstName": "John", "lastName": "Doe", "emailAddress": "something@somewhere.com", "sex": "1"

必须是:

{"user": {"firstName": "John", "lastName": "Doe", "emailAddress": "something@somewhere.com", "sex": "1"}}

在我的情况下,表单名称为" user"。

我用过CURL来测试它:

curl -v -H "Accept: application/json" -H "Content-type: application/json" -XPOST -d "{\"user\":{\"firstName\":\"John\", \"emailAddress\": \"somewhere@somehow.com\", \"password\":\"verystrongmuchpower\"}}" http://localhost.software.com/app_dev.php/api/1.0/users

由于我使用CURL测试API,因此bind和handleRequest的响应差异消失了。

如果我得到更多结论,我会尽快更新这个答案。

答案 1 :(得分:0)

我解决了这个问题:

    $user = new User;
    $form = $this->createForm(UserType::class, $user);
    $view = View::create();

    $form->submit($request->request->all());
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        $em->persist($user);
        $em->flush();

        $view->setData($form->getData());
    } else {
        $view->setData($form);
    }

    return $this->handleView($view);

不要忘记禁用CSRF验证(https://symfony.com/doc/master/bundles/FOSRestBundle/2-the-view-layer.html#csrf-validation

fos_rest:
    disable_csrf_role: ROLE_API
    #disable_csrf_role: IS_AUTHENTICATED_ANONYMOUSLY #just for testing

然后你得到一个很好的输出:

{
"code": 400,
"message": "Validation Failed",
"errors": {
    "children": {
        "name": {
            "errors": [
                "This value should not be blank."
            ]
        },
        "role": {
            "errors": [
                "This value should not be blank."
            ]
        }
    }
  }
}