Oliver Koehler
Oliver Koehler

Reputation: 721

Symfony3 deserialization of JSON does not work as expected

in a Symfony controller I have the following function:

/**
 *
 * @Route("/test", name="post_test")
 * @Method("POST")
 */   
 public function postTest(Request $request){
    $normalizer = new GetSetMethodNormalizer();

    $callback = function ($dateTime) {
       return $dateTime instanceof DateTime ? $dateTime->format(DateTime::ISO8601) : '';
    };

    $normalizer->setCallbacks(array('datum' => $callback));
    $encoder = new JsonEncoder();
    $serializer = new Serializer(array($normalizer), array($encoder));

    $test = $serializer->deserialize($request->getContent(),Test::class, 'json');
    return new Response($test->getName().":".$test->getDatum());
 }

I am trying to do the POST via curl with

curl -i -X POST http://127.0.0.1:8000/test -d '{"datum": "2016-12-20T09:01:41+0100", "name": "Alfons"}'

Payload looks like: {"name":"John Doe","datum":"2016-12-20T09:01:41+0100"}

The class to which the JSON should be serialized is like this:

class Test {
    private $name;
    private $datum;

    public function getName(){
        return $this->name;
    }

    public function setName($name){
        $this->name = $name;
    }

    public function getDatum(){
        return $this->datum;
    }

    public function setDatum($datum){
        $this->datum = $datum;
    }
}

My JSON get deserialized, which is fine. However the result are two strings in Test.name and Test.datum. What I actually want is to have a string in Test.name and a DateTime object in Test.datum.

For this reason I have entered the callback in the function above. However the callback is never called.

What am I doing wrong?

Regards

Oliver

Upvotes: 1

Views: 143

Answers (1)

Timurib
Timurib

Reputation: 2743

Unfortunately, that callbacks invoked only on serialization process, not on deserialization. See the source code: callbacks used only in the normalize() method. So, you can:

  • a) Create a DateTime object manually, in the setter for example.
  • b) Make your own Normalizer implementation (for example extends the GetSetMethodNormalizer).
  • c) Use alternative third-party solutions such as JMS Serializer, it allows to declare an attribute type for deserialization.

Upvotes: 1

Related Questions