serialization - exclude - JMSSerializerBundle. no tiene control sobre metadatos de terceros
jms exclude (2)
Tengo dos entidades que deseo serializar con JMSSerializerBundle. Music
Entity tiene un archivo de asignación con exclusion_policy: NONE
.
La entidad de Music
tiene un campo de la entidad User
de FOSUserBundle
. La entidad de User
tiene un archivo de asignación con exclusion_policy: ALL
con unos pocos campos configurados para expose: true
, por lo que se serializarán.
El problema es que el campo User
se serializa por completo. No importa si cambio el archivo de mapeo de la entidad de User
.
Así es como se ve:
#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
¿Por qué no se refiere a su propio archivo de mapeo? ¿O estoy equivocado en alguna parte?
¿Qué he intentado hasta ahora?
He leído la documentación de metadatos de terceros. Simplemente dice agregar un nuevo directorio en mi servicio de serializador. Lo he hecho, pero tengo que extender la clase FOS/UserBundle/Entity
, y eso tampoco tiene acceso a los campos protegidos principales que intento excluir.
Apuesto xxx/xxx/Entity/User:
refiere a tu propio espacio de nombres y clase .
Si es así, es la forma incorrecta de hacerlo.
Las reglas se deben aplicar a la clase donde viven las propiedades.
Dada la propiedad que expuso en su configuración, supongo que está utilizando FOSUserBundle
.
Por lo tanto, debe aplicar sus reglas en FOS/UserBundle/Model/User
.
Luego, debe agregar una configuración de JMSSerializer
para indicar dónde viven los metadatos del serializador para el espacio de nombres dado.
Debería verse así:
jms_serializer:
metadata:
auto_detection: true
directories:
FOSUserBundle:
namespace_prefix: "FOS//UserBundle"
path: "@YourUserBundle/Resources/config/serializer/fos"
En el directorio fos/
debería tener Model.User.yml
Con algo como:
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]
Detalles:
Al aplicar reglas al serializador a través de metadatos, el serializador busca la propiedad que se declara dentro de la clase que se define en los metadatos.
Ejemplo:
class Foo {
protected $foo;
}
class Bar extends Foo {
protected $bar;
}
Tus metadatos se verán así:
Foo:
exclusion_policy: ALL
properties:
foo:
expose: true
Bar:
exclusion_policy: ALL
properties:
bar:
expose: true
EL EJEMPLO A CONTINUACIÓN NO ES LA FORMA CORRECTA DE HACER
Bar:
exclusion_policy: ALL
properties:
foo:
expose: true
bar:
expose: true
si hace esto, solo se aplicarán (y se expondrán) las reglas de la bar
propiedades.
Tuve el problema de que estaba obteniendo el serializador de una manera incorrecta. Necesita JMSSerializerBundle
y use el servicio para que la configuración surta efecto.
Entonces, en lugar de:
//In controller we can use $this instead of $container
$serializer = $this->get(''jms_serializer''); //JMSSerializerBundle
Solía:
$serializer = SerializerBuilder::create()->build(); //JMSSerializer
Usar la primera forma cargará su configuración. Como uso Propel
, necesitaba ignorar todos los campos de BaseObject
:
#app/config.yml
jms_serializer:
metadata:
auto_detection: true
directories:
Propel:
namespace_prefix: ""
path: "@MySupporterBundle/Resources/config/serializer"
Tenga en cuenta que BaseObject
no tiene espacio de nombres y necesita los siguientes paquetes para que esto funcione (se solucionó antes de los metadatos 1.2):
"jms/serializer": "0.12.*",
"jms/serializer-bundle" : "0.12.*@dev",
"jms/metadata" : "1.3.*",
Así que hice este archivo:
#My/SupporterBundle/Resources/config/serializer/BaseObject.yml
BaseObject:
exclusion_policy: ALL
y para objetos específicos (en el espacio de nombres Modelo) necesita archivos (con el espacio de nombres predeterminado como Mi / OtroPaquete):
My / OtherBundle / Resources / config / serializer / Model.om.BaseClass.yml My / OtherBundle / Resources / config / serializer / Model.Class.yml
Nota: debe borrar el caché al crear nuevos archivos de serializador