为了简单起见,我有
/*
* @JMS\Discriminator(field = "type", map = {
* "one": "...\ItemOne",
* "two": "...\ItemTwo"
* })
*/
Abstract Class Item {}
.
.
.
class ItemOne extends Item {/* Contains multiple properties */}
class ItemTwo extends Item {/* Contains multiple properties */}
class Example
{
/**
* @var Item[] $items
*
* @ORM\OneToMany(targetEntity="...\Items", mappedBy="holder",cascade={"persist", "remove"})
*/
protected $items;
}
一旦我使用FOSRestBundle序列化了这个实体,一切看起来都很好,我得到了项的数组,每个元素都有一个鉴别器字段,但是在反序列化时,我得到了以下错误
"You must define a type for ...\Example::$items."
因此,为了解决这个问题,我添加了
/**
* @ORM\...
* @JMS\Type("ArrayCollection<...\Item>")
*/
protected $items;
这一次,序列化的$items
似乎仅限于父类Item
,所有对象都将丢失与子类ItemOne
和ItemTwo
相关的所有属性,并且将在没有任何鉴别器字段的情况下被序列化,因此反序列化将失败并显示错误
"The discriminator field name "type" for base-class "...\Item" was not found in input data."
我该如何解决这个问题?
编辑正如@erlangb建议的那样,这似乎是JMS Serializer
https://github.com/schmittjoh/JMSSerializerBundle/issues/292中的常见问题
尽管我不能使用上面提到的变通方法让它工作
/**
* @JMS\Discriminator(field = "type", map = {"car": "...\Test\Car", "moped":"...\Test\Moped"})
*/
abstract class Vehicle {
public $id;
}
class Car extends Vehicle {
/**
*@JMS\Type("integer")
*/
public $id;
/**
*@JMS\Type("string")
*/
public $car_at;
/**
* @JMS\VirtualProperty
*/
public function getType()
{
return 'car';
}
}
class Moped extends Vehicle {
/**
*@JMS\Type("integer")
*/
public $id;
/**
*@JMS\Type("string")
*/
public $moped_at;
/**
* @JMS\VirtualProperty
*/
public function getType()
{
return 'moped';
}
}
class Saloon
{
/**
*@JMS\Type("integer")
*/
public $id;
/**
* @JMS\Type("...\Test\Vehicle")
*/
public $veichle;
}
//In controller
$car = new Car();
$car->id = 1;
$car->car_at = "car";
$car2 = new Moped();
$car2->id = 2;
$car2->moped_at = "moped";
$saloon = new Saloon();
$saloon->veichle = $car2;
$json = $this->get('jms_serializer')->serialize($saloon,'json');
$saloon_des = $this->get('jms_serializer')->deserialize($json,'...\Saloon','json');
仍然会得到
The discriminator field name "type" for base-class "...\Test\Vehicle" was not found in input data.
或者,如果我从Saloon->veichle
中删除@JMS\Type
,我会得到
The discriminator field name "type" of the base-class "...\Test\Vehicle" conflicts with a regular property of the sub-class "...\Test\Moped".
发布于 2014-06-30 23:35:38
这是一个已知的问题。几年前我也遇到过同样的问题。我不知道他们是否解决了这个问题,但看看这里:https://github.com/schmittjoh/JMSSerializerBundle/issues/292
现在我发现在jms序列化程序中有这样的注解:
/**
* @Discriminator(field = "type", map = {"car": "Car", "moped": "Moped"})
*/
abstract class Vehicle { }
class Car extends Vehicle { }
class Moped extends Vehicle { }
您可以像这样设置虚拟属性:
class Car extends Vehicle {
/**
* @Serializer\VirtualProperty
*/
public function getType()
{
return 'car';
}
}
class Moped extends Vehicle {
/**
* @Serializer\VirtualProperty
*/
public function getType()
{
return 'moped';
}
}
试着这样做
发布于 2014-07-01 20:37:53
/**
* @JMS\Discriminator(field = "type", map = {
* "user": "User",
* "mod": "Moderator"
* })
*/
abstract class AbstractUser
{
/**
* @JMS\Type("integer")
*/
public $id;
/**
* @JMS\Type("string")
*/
public $name
}
class Moderator extends AbstractUser
{
/**
* @JMS\Type("string")
*/
public $foo;
}
class User extends AbstractUser
{
/**
* @JMS\Type("string")
*/
public $bar;
}
这是我的测试:
public function testSerializer()
{
$data = new Moderator();
$data->foo = 'foo';
$data->name = 'daniele';
$serializer = SerializerBuilder::create()->build();
$jsonContent = $serializer->serialize($data, 'json');
$obj = $serializer->deserialize($jsonContent, '..MyBundle\...\AbstractUser', json');
$this->assertTrue(get_class($obj), 'MyBundle....\Moderator');
}
我简化了名称空间,但它是有效的
https://stackoverflow.com/questions/24491222
复制相似问题