JMSSerializerBundle。无法控制第三方元数据

时间:2012-10-18 17:15:07

标签: serialization symfony symfony-2.1 symfony-2.0 jmsserializerbundle

我希望使用JMSSerializerBundle序列化两个实体。 Music实体的映射文件为exclusion_policy: NONE

Music实体的User实体的字段为FOSUserBundleUser实体的映射文件包含exclusion_policy: ALL,其中一些字段设置为expose: true,因此它们将被序列化。

问题是,User字段完全序列化。如果我更改User实体的映射文件,则无关紧要。

它的外观如下:

#My/Bundle/Resources/config/serializer/Entity.Music.yml
xxx\xxx\Entity\Music:
    exclusion_policy: NONE

#My/Bundle/Resources/config/serializer/Entity.User.yml
xxx\xxx\Entity\User:
    exclusion_policy: ALL
    properties:
        id:
            expose: true
        username:
            expose: true
        username_canonical:
            exclude: true
        email:
            exclude: true
        email_canonical:
            exclude: true
        enabled:
            exclude: true
        salt:
            exclude: true
        password:
            exclude: true
        last_login:
            exclude: true
        confirmation_token:
            exclude: true
        password_requested_at:
            exclude: true
        groups:
            exclude: true
        locked:
            exclude: true
        expired:
            exclude: true
        expires_at:
            exclude: true
        roles:
            expose: true
        credentials_expired:
            exclude: true
        credentials_expired_at:
            exclude: true

为什么它不引用它自己的映射文件?或者我错了?

我从未尝试过什么

我已阅读第三方元数据文档。它只是说在我的序列化服务中添加一个新目录。我已经这样做了,但我必须扩展FOS\UserBundle\Entity类,并且也无法访问我试图排除的父受保护字段。

2 个答案:

答案 0 :(得分:65)

我敢打赌xxx\xxx\Entity\User:指的是自己的命名空间和类

如果是,那就是错误的方式。

必须将规则应用于属性所在的类。

鉴于您在配置中公开的属性,我猜您使用的是FOSUserBundle

因此,您必须在FOS\UserBundle\Model\User上应用规则。

然后,您需要添加JMSSerializer配置,以指示序列化程序元数据在给定命名空间中的位置。

应该看起来像:

jms_serializer:
  metadata:
    auto_detection: true
    directories:
      FOSUserBundle:
        namespace_prefix: "FOS\\UserBundle"
        path: "@YourUserBundle/Resources/config/serializer/fos"

fos/目录中,您应该有Model.User.yml

有类似的东西:

FOS\UserBundle\Model\User:
  exclusion_policy: ALL
  properties:
    id:
      expose: true
      groups: [list, details]
    username:
      expose: true
      groups: [details]
    email:
      expose: true
      groups: [me]
    roles:
      expose: true
      groups: [details]

详细说明:

通过元数据将规则应用于Serializer时,Serializer会在元数据中的已定义类中查找声明的属性。

示例:

class Foo {
     protected $foo;
}

class Bar extends Foo {
     protected $bar;
}

您的元数据将如下所示:

Foo:
  exclusion_policy: ALL
  properties:
      foo: 
          expose: true

Bar:
  exclusion_policy: ALL
  properties:
      bar: 
          expose: true

下面的例子不是正确的方法

Bar:
  exclusion_policy: ALL
  properties:
      foo: 
          expose: true
      bar: 
          expose: true

如果您这样做,则只会应用(并公开)属性bar上的规则。

答案 1 :(得分:3)

我有这个问题,我以错误的方式获取序列化程序。您需要JMSSerializerBundle并使用该服务进行配置才能生效。

所以而不是:

//In controller we can use $this instead of $container
$serializer = $this->get('jms_serializer'); //JMSSerializerBundle

我用过:

$serializer = SerializerBuilder::create()->build(); //JMSSerializer

使用第一种方式将加载您的配置。由于我正在使用Propel,因此我需要忽略所有BaseObject字段:

#app/config.yml
jms_serializer:
metadata:
    auto_detection: true
    directories:
        Propel:
            namespace_prefix: ""
            path: "@MySupporterBundle/Resources/config/serializer"

请注意,BaseObject没有命名空间,您需要以下软件包才能生效(在元数据1.2之前出现错误):

        "jms/serializer": "0.12.*",
        "jms/serializer-bundle" : "0.12.*@dev",
        "jms/metadata" : "1.3.*",

所以我做了这个文件:

#My/SupporterBundle/Resources/config/serializer/BaseObject.yml
BaseObject:
    exclusion_policy: ALL

并且对于特定对象(在Model命名空间中),您需要文件(默认命名空间为My / OtherBundle):

  

我/ OtherBundle /资源/配置/串行器/ Model.om.BaseClass.yml   我/ OtherBundle /资源/配置/串行器/ Model.Class.yml

注意:您需要在创建新的序列化文件时清除缓存