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

25

我有两个实体想要使用JMSSerializerBundle进行序列化。 Music 实体有一个映射文件,其中 exclusion_policy: NONE

Music 实体具有来自 FOSUserBundle 的实体 User 的字段。 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类,而这也无法访问我正在尝试排除的父受保护字段。

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属性上的规则会被应用(并暴露)。


我该如何移除继承自FOSUserBundle/Entity/User的MyBundle/Entity/User实体的映射? - tolgap
1
很抱歉要提出这个问题和答案,但我注意到“directories”和“auto_detection”似乎无法搭配使用。如果我尝试覆盖JMS查找第三方元数据的位置,它不会应用它。但是,如果我将相同的元数据放在默认/预期路径中,并注释掉“jms_serializer”中的目录配置,则会被应用。我假设这两个应该共同工作? - Sean Quinn
为什么这些信息不能包含在官方文档中...我花了太长时间才找到它。 - Chris
@Chris,随意提交PR ;) - Boris Guéry
我在排除FOS\UserBundle\Model\User属性方面遇到了问题,最终我发现你应该按照User类中定义的方式定义这些属性。因此,$plainPassword和其他属性也应该使用camelCase在yml中定义。 - Genar
显示剩余4条评论

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

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

My/OtherBundle/Resources/config/serializer/Model.om.BaseClass.yml My/OtherBundle/Resources/config/serializer/Model.Class.yml

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接