我希望使用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
类,并且也无法访问我试图排除的父受保护字段。
答案 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
注意:您需要在创建新的序列化文件时清除缓存