$this->get('request')->getContent()
returns
{"id":2,"username":"[email protected]","username_canonical":"[email protected]", ... }
Deserialization:
$data = $serializer->deserialize($this->get('request')->getContent(), 'My\SpecialBundle\Entity\User', 'json');
throws:
"request.CRITICAL: Uncaught PHP Exception JMS\Serializer\Exception\RuntimeException: "You must define a type for FOS\UserBundle\Model\User::$username." at ...\vendor\jms\serializer\src\JMS\Serializer\GenericDeserializationVisitor.php line 170 [] []"
Whats wrong?! How can I deserialize the json to a user object correctly? I use symfony 2.3
Well, the error message tells you what you need to do: You must define a type for FOS\UserBundle\Model\User::$username.
How should I define that type? In my User class that extends fosuser base class I have no $username, its defined in the parent class.
Use XML or YAML to define the metadata for the FOSUserBundle class (you cannot use annotations as it would require modifying the FOSUserBundle source code, which is a bad idea). Here is how I configured it in my project:
# app/config/config.yml
jms_serializer:
metadata:
directories:
- { path: '%kernel.root_dir%/Resources/FOSUserBundle/serializer', namespace_prefix: 'FOS\UserBundle' }
# app/Resources/FOSUserBundle/serializer/Model.User.yml
FOS\UserBundle\Model\User:
exclusion_policy: ALL
properties:
id:
expose: true
username:
expose: true
email:
expose: true
enabled:
expose: true
locked:
expose: true
Added your code but problem remains. I still get the same error.
My code shows how to provide mapping for classes in vendor packages. But you still need to map the type. My config above copied from my project does not specify it as I never deserialize the user, I only serialize it.
Well but how do I define that type? I can define a type for my own attributes, but what about the attributes inherited from BaseUser (they have no type annotation)?
@ArtworkAD Define it in YAML instead of annotations
Ok it seems that it is working now. But last_login field is not exposed. Any ideas why?
FOS\UserBundle\Model\User:
exclusion_policy: ALL
properties:
id:
expose: true
username:
type: string
expose: true
usernameCanonical:
type: string
exclude: true
email:
type: string
expose: true
enabled:
type: boolean
expose: true
locked:
type: boolean
expose: true
last_login:
type: datetime
expose: true
updated_at:
type: datetime
expose: true
created_at:
type: datetime
expose: true
To expose/exclude my custom user attributes I have to define a User.yml in My/SpecialBundle/Resources/config/serializer?
@ArtworkAD for your own class, you can choose the format you want: YAML, XML or annotations
@stof ok. When I remove created_at and updated_at from app/Resources/FOSUserBundle/serializer/Model.User.yml they are still exposed. Very strange, any ideas why this happens? Do I have to exclude them explicitly?
These fields are not defined in FOS\UserBundle\Model\User. You need to configure them in the mapping of the right class
The default exclusion policy is none, so properties are exposed unless blacklisted (I changed it to a whitelist in my config of FOS\UserBundle\Model\User above to make it shorter)
Thank you, I had a typo, it is lastLogin instead of last_login, and type is DateTime instead of datetime. Now it works.
Anyone else that stumbles upon this issue and is using annotations:
Class Model
{
/**
* @ORM\Column(type="boolean", nullable=true)
* @Type("boolean")
*/
protected $property;
}
Similarly if you are trying to de-serialize objects like the OP, this worked for me:
use App\MyClass;
class Model
{
/**
* @var MyClass
* @Type(MyClass::class)
*/
private $property;
}
Most helpful comment
Anyone else that stumbles upon this issue and is using annotations: