Symfony2 FOSRestBundle使用Request Body Listener提交有关PUT操作的表单

时间:2016-06-14 10:17:03

标签: forms symfony fosrestbundle

引用这个问题:JMS Serializer DateTime not deserializing?,我已将其缩小到以下内容:

我有一个使用Request Body Listener的put动作的控制器:

/**
 * @ParamConverter("client", converter="fos_rest.request_body")
 */
public function putClientAction($id, Client $client)
{
    $logger = $this->get('logger');
    $logger->info(serialize((array) $client));
    $logger->info("ID: " . $id);


    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('SomeBundle:Client')->find($id);


    $logger->info(serialize($entity));

    $form = $this->get('form.factory')->createNamed('', new \SomeBundle\Form\ClientType(), $entity);
    $form->submit((array) $client, false);

    $logger->info(serialize($entity));

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

    return $this->get('fos_rest.view_handler')->handle($this->view(null, Codes::HTTP_OK));
}

我的问题涉及$form->submit()调用,或者更确切地说,我将如何进行实际提交传入的$client实体?我已经尝试提交对象或它的(数组)表示,$clearmissing标志设置为false以避免传入null值,但是UPDATE永远不会发生。

可以肯定的是,记录的实体表示看起来很好,只是$entity永远不会被$client的值填充。

对我做错了什么有任何暗示?

修改

这是PUT请求的样子:

{
  "shortname":"...",
  "officialname":"...",
  "shortinfo":"..." 
  ...
}  

编辑2

我已将其缩小(再次)到DateTime数据类型的问题:

...
$logger->info("REQUEST" . print_r($request->request->all(), true));
$form = $this->get('form.factory')->createNamed('', new Type(), $entity);
$form->submit($request, false);

$logger->info($form->getData()->getUpdatedAt()->format('Y-m-d\TH:i:sP'));

$request对象包含更新的DateTime,但它永远不会传递给表单(第二个日志显示原始日期)。表格Type

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('updatedAt', 'datetime', array('format' => 'Y-m-d\TH:i:sP'))
}

我猜这是Symfony Forms和DateTime对象的问题,然后呢?

1 个答案:

答案 0 :(得分:0)

问题在于您提交数据的方式。你应该使用不那么复杂的方式。

以下是示例:

public function putPostAction(Post $post, Request $request)
{
    $em     = $this->getDoctrine()->getManager();
    $form   = $this->createForm('content_post',$post);

    $form->submit($request);

    if($form->isValid()){
        $em->persist($form->getData());
        $em->flush();

        return $post;
    }

    return $form;
}

您不需要在代码中查询客户端,因为控制器会自动为您转换它。

此外,您应该使用Request对象,它将包含您提交的所有数据。

$ form-> submit($ request)在这里有一个关键部分。

$ form将返回所有验证错误。

我的FOSRestConfig

fos_rest:
    param_fetcher_listener: true
    routing_loader:
        default_format: json
    view:
        view_response_listener: force