我将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的文档很差,它说的都是关于获取内容的,但几乎没有关于发布的内容。
任何帮助都非常感激。
答案 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."
]
}
}
}
}