簡體   English   中英

Symfony2 FOSRestBundle PUT Action FORM返回空結果

[英]Symfony2 FOSRestBundle PUT Action FORM returns empty results

我正在使用Symfony 2.2和最新版本的FOSRestBundle。 所以我設法讓大多數動作都有效,但我似乎遇到了FormBuilder的問題,我正在通過PUT調用請求。

我檢查了請求對象,它來自我的Backbone.je模型​​,因為它應該(.save())但是在綁定到表單后,實體返回只有id導致flush()拋出錯誤,因為必需的字段沒有填補。

控制器中的操作:

header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS ');
header('Allow GET, POST, PUT, DELETE, OPTIONS ');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, *');

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\Rest\Util\Codes;
use Symfony\Component\HttpFoundation\Request;
use Greenthumbed\ApiBundle\Entity\Container;
use Greenthumbed\ApiBundle\Form\ContainerType;

class ContainerController extends FOSRestController implements ClassResourceInterface
{
/**
 * Put action
 * @var Request $request
 * @var integer $id Id of the entity
 * @return View|array
 */
public function putAction(Request $request, $id)
{
    $entity = $this->getEntity($id);
    $form = $this->createForm(new ContainerType(), $entity);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->view(null, Codes::HTTP_NO_CONTENT);
    }

    return array(
        'form' => $form,
    );
}

/**
 * Get entity instance
 * @var integer $id Id of the entity
 * @return Container
 */
protected function getEntity($id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('GreenthumbedApiBundle:Container')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Container entity');
    }

    return $entity;
}

被稱為的表格:

namespace Greenthumbed\ApiBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ContainerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('description')
            ->add('isVisible')
            ->add('type')
            ->add('size')
            ->add('creationDate')
            ->add('userId')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Greenthumbed\ApiBundle\Entity\Container',
            'csrf_protection' => false,
        ));
    }

    public function getName()
    {
        return 'greenthumbed_apibundle_containertype';
    }
}

到目前為止我已經嘗試了所有內容,但我對Symfony還是比較新的,我無法理解為什么$實體不包含請求收到的值。

僅供參考:我嘗試手動操作,例如在實例化具有請求ID的Container類,並使用setter將值輸入到其中並且它工作正常,我只是想以正確的方式做事情,因為Symfony建議它應該完成。

非常感謝你提前。

嘗試在putAction中更改以下行:

$form = $this->createForm(new ContainerType(), $entity);

至:

$form = $this->createForm(new ContainerType(), $entity, array('method' => 'PUT'));

我認為你遇到了同樣的問題:錯誤在於Form的名稱。

在表單定義中,名稱為“greenthumbed_apibundle_containertype”。 public function getName(){return'greenthumbed_apibundle_containertype'; }

因此,要將請求綁定到此表單,json應該如下所示:

{"greenthumbed_apibundle_containertype": [{"key": "value"}]}

由於Backbone .save()方法提供了這種json

{"key":"value","key2":"value2"}

你必須從表單中刪除名稱:

public function getName()
{
    return '';
}

一般來說,如果你想發布一個像占位符一樣的json

"something":{"key":"value"}

你的表格名稱必須是“某事”

從我自己的問題在這里

使用ParamConverter自動將您的實體作為參數注入方法中。

use Greenthumbed\ApiBundle\Entity\Container;

// ...

public function putAction(Request $request, Container $container)
{
    $form = $this->createForm(new ContainerType(), $container);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        // Entity already exists -> no need to persist!
        // $em->persist($entity);   

        $em->flush();

        return $this->view(null, Codes::HTTP_NO_CONTENT);
    }

    return array('form' => $form);
}

請參閱http://symfony.com/doc/current/cookbook/routing/method_parameters.html

不幸的是,生活並不那么簡單,因為大多數瀏覽器不支持發送PUT和DELETE請求。 幸運的是,Symfony2為您提供了一種解決此限制的簡單方法。 通過在查詢字符串中包含_method參數或HTTP請求的參數,Symfony2將在匹配路由時將其用作方法。 如果表單的提交方法不是GET或POST,則表單會自動包含此參數的隱藏字段。 有關詳細信息,請參閱表單文檔中的相關章節。

http://symfony.com/doc/current/book/forms.html#book-forms-changing-action-and-method

如果表單的方法不是GET或POST,而是PUT,PATCH或DELETE,Symfony2將插入一個名為“_method”的隱藏字段,用於存儲此方法。 表單將在普通POST請求中提交,但Symfony2的路由器能夠檢測“_method”參數,並將請求解釋為PUT,PATCH或DELETE請求。 有關更多信息,請閱讀食譜章節“如何在路由中使用GET和POST之外的HTTP方法”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM