FOSRestBundle EntityType不在JSON中工作

时间:2018-03-02 15:54:48

标签: php json symfony fosrestbundle

我正在使用Symfony 3.4和FOSRestBundle作为我的API 所有服务都正常工作,除了我发布一个带有表单和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示例中做错了什么?

2 个答案:

答案 0 :(得分:2)

只需添加第一个答案,您还需要修改JSON有效负载。

您必须直接输入您的mobile_app_user ID:

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

答案 1 :(得分:1)

由于您将json对象作为请求正文而不是普通的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标题,就好像它已设置为' multipart / form-data'虽然在其体内有json有效载荷 - 解码器将失败。