25

我有两个实体希望使用 JMSSerializerBundle 进行序列化。Music实体有一个映射exclusion_policy: NONE文件。

Music实体具有User来自的实体的字段FOSUserBundle。该User实体有一个映射文件,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类,并且它也无法访问我试图排除的父受保护字段。

4

2 回答 2

66

我打赌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]

细节:

当通过元数据将规则应用于序列化器时,序列化器会查找在元数据中定义的类中声明的属性。

例子:

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应用(并公开)属性上的规则。

于 2012-10-18T19:11:17.870 回答
4

我有这个问题,我以错误的方式获取序列化程序。您需要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

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

我的/OtherBundle/Resources/config/serializer/Model.om.BaseClass.yml 我的/OtherBundle/Resources/config/serializer/Model.Class.yml

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

于 2013-04-18T10:42:15.270 回答