FOSRestBundle EntityType 在 JSON 中不工作
FOSRestBundle EntityType not working in JSON
我正在为我的 API 使用 Symfony 3.4 和 FOSRestBundle。
所有服务都运行良好,除了我在其中发布带有表单和 EntityType
字段的实体。
控制器:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
$form->handleRequest($request);
dump($form->isSubmitted(), $form->isValid());die;
}
实体属性:
/**
* @var MobileAppUser
*
* @ORM\ManyToOne(targetEntity="MobileAppUser")
* @ORM\JoinColumn(name="mobile_app_user_id", referencedColumnName="id", nullable=false)
* @Assert\NotBlank
*/
protected $mobileAppUser;
表格:
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('mobile_app_user', EntityType::class, array(
'class' => 'AppBundle:MobileAppUser',
))
->add('save', SubmitType::class)
;
}
它在 正常 POST 下工作正常:
curl -X POST http://mysite.local/api/users/1/create-assistance-call -F 'assistance_call[mobile_app_user]=26'
dump($form->isSubmitted(), $form->isValid());die; // true and true
不工作 JSON 格式:
curl -X POST \
http://mysite.local/api/users/1/create-assistance-call \
-d '{
"assistance_call": {
"mobile_app_user": {
"id": 1
}
}
}'
dump($form->isSubmitted(), $form->isValid());die; // false and false
我在 JSON 示例中做错了什么?
由于您发送 json object 作为请求 body 而不是正常的 POST 字段 - 您应该 json_decode
首先请求内容,然后然后使用 $form->submit(...)
将数据加载到您的表单中。旧的好东西 handleRequest()
在这里不行。看看下面的例子:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
//Notice the "true" argument passed to the json_decode
$data = json_decode($request->getContent(), true);
$form->submit($data);
dump($form->isSubmitted(), $form->isValid());die;
}
您也可以使用 FOSRestBundle BodyListener 为您解码 json。为此 - 添加以下配置条目:
fos_rest:
body_listener:
decoders:
json: fos_rest.decoder.jsontoform
这仍然不是 $form->handleRequest()
一个好的选择,因为它只允许每个表单使用一种方法,因此如果您将表单配置为执行 POST - PUT 请求将始终失败任何明确的错误消息。
那么你可以这样修改上面的代码:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
$form->submit($request->request->all());
dump($form->isSubmitted(), $form->isValid());die;
}
注意你发送的 Content-Type
header 就好像它被设置为 'multipart/form-data' 而在其 body 中有 json 有效负载 - 解码器将失败。
只是为了添加到第一个答案,您还需要修改您的 JSON 负载。
你必须直接输入你的 mobile_app_user id :
{
"assistance_call": {
"mobile_app_user": 1
}
}
我正在为我的 API 使用 Symfony 3.4 和 FOSRestBundle。
所有服务都运行良好,除了我在其中发布带有表单和 EntityType
字段的实体。
控制器:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
$form->handleRequest($request);
dump($form->isSubmitted(), $form->isValid());die;
}
实体属性:
/**
* @var MobileAppUser
*
* @ORM\ManyToOne(targetEntity="MobileAppUser")
* @ORM\JoinColumn(name="mobile_app_user_id", referencedColumnName="id", nullable=false)
* @Assert\NotBlank
*/
protected $mobileAppUser;
表格:
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('mobile_app_user', EntityType::class, array(
'class' => 'AppBundle:MobileAppUser',
))
->add('save', SubmitType::class)
;
}
它在 正常 POST 下工作正常:
curl -X POST http://mysite.local/api/users/1/create-assistance-call -F 'assistance_call[mobile_app_user]=26'
dump($form->isSubmitted(), $form->isValid());die; // true and true
不工作 JSON 格式:
curl -X POST \
http://mysite.local/api/users/1/create-assistance-call \
-d '{
"assistance_call": {
"mobile_app_user": {
"id": 1
}
}
}'
dump($form->isSubmitted(), $form->isValid());die; // false and false
我在 JSON 示例中做错了什么?
由于您发送 json object 作为请求 body 而不是正常的 POST 字段 - 您应该 json_decode
首先请求内容,然后然后使用 $form->submit(...)
将数据加载到您的表单中。旧的好东西 handleRequest()
在这里不行。看看下面的例子:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
//Notice the "true" argument passed to the json_decode
$data = json_decode($request->getContent(), true);
$form->submit($data);
dump($form->isSubmitted(), $form->isValid());die;
}
您也可以使用 FOSRestBundle BodyListener 为您解码 json。为此 - 添加以下配置条目:
fos_rest:
body_listener:
decoders:
json: fos_rest.decoder.jsontoform
这仍然不是 $form->handleRequest()
一个好的选择,因为它只允许每个表单使用一种方法,因此如果您将表单配置为执行 POST - PUT 请求将始终失败任何明确的错误消息。
那么你可以这样修改上面的代码:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
$form->submit($request->request->all());
dump($form->isSubmitted(), $form->isValid());die;
}
注意你发送的 Content-Type
header 就好像它被设置为 'multipart/form-data' 而在其 body 中有 json 有效负载 - 解码器将失败。
只是为了添加到第一个答案,您还需要修改您的 JSON 负载。
你必须直接输入你的 mobile_app_user id :
{
"assistance_call": {
"mobile_app_user": 1
}
}