Php FOSRestBundle EntityType在JSON中不起作用

Php FOSRestBundle EntityType在JSON中不起作用,php,json,symfony,fosrestbundle,Php,Json,Symfony,Fosrestbundle,我正在为我的API使用Symfony 3.4和FOSRestBundle。 除此之外,所有的服务都运行良好,我正在发布一个带有表单和EntityType字段的实体 控制器: public function createAssistanceCallAction(Request $request) { $assistanceCall = new AssistanceCall(); $form = $this->createForm(AssistanceCallType::cla

我正在为我的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;
表格:

它与正常帖子一起工作正常

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对象作为请求主体发送,而不是作为普通的POST字段发送-您应该先对请求内容进行解码,然后使用
$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;
}

注意您发送的
内容类型
头,就好像它在正文中有json负载时被设置为“多部分/表单数据”一样-解码器将失败。

因为您将json对象作为请求正文而不是普通的POST字段发送,所以您应该先对
json\u解码
请求内容,然后使用
$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;
}

请注意您发送的
内容类型
标题,就好像它被设置为“multipart/form data”,而正文中有json负载-解码器将失败。

只需添加到第一个答案中,您还需要修改json负载

您必须直接输入您的移动应用程序用户id:

{
    "assistance_call": {
        "mobile_app_user": 1
    }
}

要添加到第一个答案中,还需要修改JSON负载

您必须直接输入您的移动应用程序用户id:

{
    "assistance_call": {
        "mobile_app_user": 1
    }
}

FOSResuBundle不应该自动将传入的JSON数据转换为POST吗?更新了我的答案非常有趣的答案。非常感谢。FOSResuBundle不应该自动将传入的JSON数据转换为POST吗?更新了我的答案非常有趣的答案。非常感谢。