FOSRestBundle和JMS Serializer,在提交JSON时出错

One*_*ema 4 php mongodb symfony doctrine-odm fosrestbundle

我一直在尝试Symfony 2.2,FOSRest Bundle(使用JMS Serializer)和使用MongoDB的Doctrine ODM.

经过几个小时试图找出如何正确设置FOSRest捆绑包后,我仍然遇到一些麻烦:我有一个非常简单的路线,返回产品和价格列表.每当我请求HTML格式时,我得到正确的响应,但如果我请求任何其他格式(JSON,XML),我会收到错误:

[{"message": "Resources are not supported in serialized data. Path: Monolog\\Handler\\StreamHandler -> Symfony\\Bridge\\Monolog\\Logger -> Doctrine\\Bundle\\MongoDBBundle\\Logger\\Logger -> Doctrine\\Bundle\\MongoDBBundle\\Logger\\AggregateLogger -> Doctrine\\ODM\\MongoDB\\Configuration -> Doctrine\\MongoDB\\Connection -> Doctrine\\ODM\\MongoDB\\LoggableCursor",
    "class": "JMS\\Serializer\\Exception\\RuntimeException",...
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到完整的错误信息

我当前的设置非常简单:我创建了一个到控制器的单一路径,返回产品列表和价格(我按照这个例子来创建产品文档).

这是路线:

rest_product:
    type: rest
    resource: Onema\RestApiBundle\Controller\ProductController
Run Code Online (Sandbox Code Playgroud)

这是控制器:

<?php
namespace Onema\RestApiBundle\Controller;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\Rest\Util\Codes;
use JMS\Serializer\SerializationContext;
use Onema\RestApiBundle\Document\Product;

class ProductController extends FOSRestController implements ClassResourceInterface
{
    public function getAction()
    {
        $dm = $this->get('doctrine_mongodb')->getManager();
        $products = $dm->getRepository('RestApiBundle:Product')->findAll();

        if(!$products)
        {
            throw $this->createNotFoundException('No product found.');
        }

        $data = array('documents' => $products);         
        $view = $this->view($data, 200);
        $view->setTemplate("RestApiBundle:Product:get.html.twig");
        return $this->handleView($view);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是从控制器Resources/Product/get.html.twig调用的视图:

<ul>
{% for document in documents %}
<li>
    {{ document.name }}<br />
    {{ document.price }}
</li>
{% endfor %}
</ul>
Run Code Online (Sandbox Code Playgroud)

任何想法为什么这将适用于一种格式而不是其他格式?还有什么我应该设置的吗?

更新: 这是我一直在使用的配置值.在app/config/config.yml结束时我有这个:

sensio_framework_extra:
    view:    { annotations: false }
    router:  { annotations: true }

fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener: true
    view:
        formats:
            json: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
        view_response_listener: 'force'
Run Code Online (Sandbox Code Playgroud)

解决方法:

做了一些研究我遇到了另一个错误,引导我提出这个问题和答案:

/sf/answers/982145251/

一旦我摆脱了Doctrine\ODM\MongoDB\LoggableCursor通过将每个结果添加到这样的数组:

$productsQ = $dm->getRepository('RestApiBundle:Product')->findAll();

foreach ($productsQ as $product) {
    $products[] = $product;
}

return $products;
Run Code Online (Sandbox Code Playgroud)

我开始以正确的格式获得结果.这是一种蹩脚的解决方案,仍然希望找到更好的答案来解决这个问题.

Bat*_*Bit 6

如果你想得到RestApiBundle:Product文档的集合,你必须在从repository调用find方法或从查询构建器调用getQuery方法之后调用方法"toArray"

/**
 * @Route("/products.{_format}", defaults={"_format" = "json"})
 * @REST\View()
 */
public function getProductsAction($_format){
    $products = $this->get('doctrine_mongodb')->getManager()
        ->getRepository('RestApiBundle:Product')
        ->findAll()->toArray();

    return $products;
}
Run Code Online (Sandbox Code Playgroud)

您也可以调用array_values($ products)来正确排序排除策略