问题
I have two entities I wish to serialize with the JMSSerializerBundle. The Music
Entity has a mapping-file with exclusion_policy: NONE
.
The Music
entity has a field of the entity User
from FOSUserBundle
. The User
entity has a mapping-file with exclusion_policy: ALL
with a few fields set to expose: true
, so they will be serialized.
The problem is, the User
field gets fully serialized. It does not matter if I change the mapping-file of the User
entity.
This is how it looks:
#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
Why does it not refer to it's own mapping file? Or am I mistaken somewhere?
What have I tried thusfar
I have read the third party meta data documentation. It simply says to add a new directory in my serializer service. I have done that, but I have to extend the FOS\UserBundle\Entity
class, and that also does not have access to the parent protected fields I'm trying to exclude.
回答1:
I bet xxx\xxx\Entity\User:
refers to your own namespace and class.
If it is, it is the wrong way to do.
The rules must be applied to the class where the properties live.
Given the property you exposed in your configuration, I guess you're using FOSUserBundle
.
Therefore, you must apply your rules on FOS\UserBundle\Model\User
.
Then you need to add a JMSSerializer
config to indicate where the serializer metadata live for the given namespace.
It should look like:
jms_serializer:
metadata:
auto_detection: true
directories:
FOSUserBundle:
namespace_prefix: "FOS\\UserBundle"
path: "@YourUserBundle/Resources/config/serializer/fos"
In fos/
directory you should have Model.User.yml
With something like:
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]
Details:
When applying rules to the Serializer through metadata, the Serializer looks for the property which are declared inside the class which is defined in the Metadata.
Example:
class Foo {
protected $foo;
}
class Bar extends Foo {
protected $bar;
}
Your metadata will look like this:
Foo:
exclusion_policy: ALL
properties:
foo:
expose: true
Bar:
exclusion_policy: ALL
properties:
bar:
expose: true
THE EXAMPLE BELOW IS NOT THE CORRECT WAY TO DO
Bar:
exclusion_policy: ALL
properties:
foo:
expose: true
bar:
expose: true
if you do this, only the rules on the property bar
will be applied (and exposed).
回答2:
I had this problem that I was getting the serializer in a wrong way. You need JMSSerializerBundle
and use the service for configuration to take effect.
So instead of:
//In controller we can use $this instead of $container
$serializer = $this->get('jms_serializer'); //JMSSerializerBundle
I used:
$serializer = SerializerBuilder::create()->build(); //JMSSerializer
Using the first way will load your configuration. Since I'm using Propel
, I needed to ignore all BaseObject
fields:
#app/config.yml
jms_serializer:
metadata:
auto_detection: true
directories:
Propel:
namespace_prefix: ""
path: "@MySupporterBundle/Resources/config/serializer"
Note that BaseObject
has no namespace and you need the following packages for this to work (bugged before metadata 1.2):
"jms/serializer": "0.12.*",
"jms/serializer-bundle" : "0.12.*@dev",
"jms/metadata" : "1.3.*",
So I made this file:
#My/SupporterBundle/Resources/config/serializer/BaseObject.yml
BaseObject:
exclusion_policy: ALL
and for specific objects(in Model namespace) you need files (with default namespace as My/OtherBundle):
My/OtherBundle/Resources/config/serializer/Model.om.BaseClass.yml My/OtherBundle/Resources/config/serializer/Model.Class.yml
Note: You need to clear cache when creating new serializer files
来源:https://stackoverflow.com/questions/12960141/jmsserializerbundle-no-control-over-third-party-meta-data