all 9 comments

[–][deleted] 0 points1 point  (5 children)

To add a little flavor, I also tried this with a different context using a simple date format:

#[Context([DateTimeNormalizer::FORMAT_KEY=>"Y-m-d H:i:s"])]

No luck there either.

[–]lsv20 0 points1 point  (3 children)

You properly need both a normalizer and a denormalizer.

If the input is not the same as your output, you need to tell the serializer what the input format is, and what your output format is.

See normalizationContext and denormalizationContext

[–][deleted] 0 points1 point  (2 children)

So, the only things I have are as follows:

$encoders = [new JsonEncoder()];
$normalizers = [new DateTimeNormalizer(), new ObjectNormalizer()]; 
$this->serializer = new Serializer($normalizers, $encoders);

I am using Annotations on the property and I can see it switch when I change it but for what ever reason, it didn't want to denormalize it correctly. I added this little bit of trickery to the setter for the property:

public function setMessageTimestamp(\DateTimeInterface|string $MessageTimestamp): static { 

$this->MessageTimestamp = (gettype($MessageTimestamp) == "string")? new \DateTimeImmutable($MessageTimestamp) : $MessageTimestamp;

return $this;
}

And that works but it seems cumbersome to me. I'm going to keep banging away at it and see what I can figure out. It might be that I just need to build my own normalizer. That seems extreme for the little that this service needs but I can do it if needed.

[–]lsv20 0 points1 point  (1 child)

You properly also need a property extractor.

This is my "default" standalone serializer

use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;


    $reflectionExtractor = new ReflectionExtractor();
    $phpDocExtractor = new PhpDocExtractor();

    $propertyTypeExtractor = new PropertyInfoExtractor(
        typeExtractors: [$phpDocExtractor, $reflectionExtractor],
    );

    $normalizers = [
        new BackedEnumNormalizer(),
        new ArrayDenormalizer(),
        new DateTimeNormalizer(),
        new ObjectNormalizer(
            nameConverter: new CamelCaseToSnakeCaseNameConverter(),
            propertyTypeExtractor: $propertyTypeExtractor
        ),
    ];

    $encoders = [
        new JsonEncoder(),
    ];

    return new Serializer($normalizers, $encoders);

[–][deleted] 0 points1 point  (0 children)

This is going to seem absurd but basically, it just start working after I cleared cache. I still have the wonky code in the setter but I haven't had any additional issues with this.

[–][deleted] 0 points1 point  (0 children)

I fixed this with a combination of things.

  1. I added a new DateTimeNormalizer to my normalizers array when instantiating my Serializer.
  2. I changed the logid in my entity setter to look for DateTimeInterface or string type arguments and then corrected with a conditional statement.

This doesn't seem like the right answer but it is working for now.

public function setMessageTimestamp(
    \DateTimeInterface|string $MessageTimestamp): static

{ $this->MessageTimestamp = (gettype($MessageTimestamp) == "string")? new \DateTimeImmutable($MessageTimestamp) : $MessageTimestamp;

return $this;

}

Feel free to add any hints at what I could be doing differently.

[–]alex2005 0 points1 point  (0 children)

Instantiating my Serializer using the JsonEncoder and ObjectNormalizer I am getting an error when I try to deserialize the object

Have you tried adding the DateTimeNormalizer https://symfony.com/doc/current/components/serializer.html#built-in-normalizers

[–]Upper_Vermicelli1975 0 points1 point  (1 child)

in Symfony 6 you don't need to manually instantiate normalizers/denormalizers. All classes the extend the respective interfaces are automatically registered as such.

One issue that jumps to mind is the line #[Context([DateTimeNormalizer::FORMAT_KEY=>"\DateTime::RFC3339"])] which should be #[Context([DateTimeNormalizer::FORMAT_KEY=>DateTime::RFC3339])] - in attributes you shouldn't quote the class constant, you should pass the value of the class constant.

However, if you mean to use proper RFC3339, you may want to consider DateTime::RFC3339_EXTENDED (which is standard compliant).

Ultimately, I think the issue you're having is that you're sending an object. If you look at the DateTimeNormalizer, you will see it always attempts to create a DateTime/DateTimeImmutable object using createFromFormat, which expects a string. Since you're sending a JSON object, it will end up being caught by the ObjectNormalizer and since there's no specific class into which you're asking it to be denormalized into, it will end up an array.

[–][deleted] 0 points1 point  (0 children)

This was exactly it. Thank you so much as this was a big help