我正在使用Symfony 2.7.39和FOSRestBundle来构建一个简单的REST api . 在这种情况下,我有这个实体:
class DocumentacionMaquina extends Documentacion
{
/**
* @ORM\ManyToOne(targetEntity="PDCA\RestBundle\Entity\Archivo", cascade={"all"})
* @ORM\JoinColumn(name="declaracion_conformidad_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
*
* @Serializer\Groups({"details"})
*/
private $declaracion_conformidad;
// ...
}
ArchivoType:
class ArchivoType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nombre');
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'PDCA\RestBundle\Entity\Archivo',
'csrf_protection' => false,
'cascade_validation' => true
));
}
}
DocumentacionMaquinaType:
class DocumentacionMaquinaType extends DocumentacionType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('maquina', 'entity', array(
'class' => 'PDCA\RestBundle\Entity\Maquina'
))
->add('declaracion_conformidad', new ArchivoType(),
array('required'=>false)
)
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'PDCA\RestBundle\Entity\DocumentacionMaquina',
'csrf_protection' => false,
'cascade_validation' => true
));
}
}
当我创建一个新的DocumentacionMaquina实体启动POST时,它按预期工作:
{
"pdca_restbundle_documentacion":
{
"maquina": 752,
"declaracion_conformidad": {
"nombre": "fichero10"
}
}
但我想发送一个null(编辑实体并使用可选的Archivo创建新实体):
{
"pdca_restbundle_documentacion":
{
"maquina": 752,
"declaracion_conformidad": null
}
这是我发送空值时的验证错误:
此值无效 .
在我的控制器中:
$entity = new DocumentacionMaquina();
$form = $this->createForm(new DocumentacionMaquinaType(), $entity, array('method' => $request->getMethod()));
$form->submit($request->get($form->getName()), false);
if !($form->isValid()) {
return $this->view(array('form' => $form), Codes::HTTP_BAD_REQUEST);
}
任何帮助将不胜感激 .
EDIT #1 我创建了一个简单的实体,没有继承用于测试,但结果相同 .
实体Prueba:
namespace PDCA\RestBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
*/
class Prueba
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @Serializer\Groups({"list", "details"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="PDCA\RestBundle\Entity\Hijo", cascade={"all"})
* @ORM\JoinColumn(name="marcado_ce_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
*
* @Serializer\Groups({"list", "details"})
*/
private $marcado_ce;
/**
* @ORM\Column(type="string", unique=false, length=255, nullable=false)
*
* @Serializer\Groups({"list", "details"})
*
* @Assert\NotBlank()
* @Assert\Length(max=255)
*/
private $nombre;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set marcado_ce
*
* @param \DateTime $marcado_ce
* @return Prueba
*/
public function setMarcadoCe(Hijo $marcado_ce = null)
{
$this->marcado_ce = $marcado_ce;
return $this;
}
/**
* Get marcado_ce
*
* @return \DateTime
*/
public function getMarcadoCe()
{
return $this->marcado_ce;
}
/**
* Set nombre
*
* @param string $nombre
* @return Prueba
*/
public function setNombre($nombre)
{
$this->nombre = $nombre;
return $this;
}
/**
* Get nombre
*
* @return string
*/
public function getNombre()
{
return $this->nombre;
}
}
实体Hijo
namespace PDCA\RestBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
*
*/
class Hijo
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @Serializer\Groups({"list", "details", "backend_creacion"})
*/
private $id;
/**
* @ORM\Column(type="string", unique=false, length=255, nullable=false)
*
* @Serializer\Groups({"list", "details"})
*
* @Assert\NotBlank()
* @Assert\Length(max=255)
*/
private $nombre;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nombre
*
* @param string $nombre
* @return Artchivo
*/
public function setNombre($nombre)
{
$this->nombre = $nombre;
return $this;
}
/**
* Get nombre
*
* @return string
*/
public function getNombre()
{
return $this->nombre;
}
}
PruebaType和HijoType:
namespace PDCA\RestBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use PDCA\RestBundle\Entity\Prueba;
class PruebaType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre')
->add('marcado_ce', new HijoType(), array('required'=>false))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
/** @var OptionResolver $resolver */
$this->configureOptions($resolver);
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'PDCA\RestBundle\Entity\Prueba',
'csrf_protection' => false
));
}
/**
* @return string
*/
public function getName()
{
return 'pdca_restbundle_prueba';
}
}
输入Hijo
namespace PDCA\RestBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class HijoType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
/** @var OptionResolver $resolver */
$this->configureOptions($resolver);
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'PDCA\RestBundle\Entity\Hijo',
'csrf_protection' => false
));
}
/**
* @return string
*/
public function getName()
{
return null;
}
}
控制器:
$entity = new Prueba();
$form = $this->createForm(new PruebaType(), $entity, array('method' => $request->getMethod()));
$form->submit($request->get($form->getName()), false);
if ($form->isValid()) {
//Persist $entity
}
return $this->view(array('form' => $form), Codes::HTTP_BAD_REQUEST);
当我使用子实体进行POST时,实体Prueba和Hija会持续存在:
{
"pdca_restbundle_prueba": {
"nombre": "nombre prueba",
"marcado_ce":
{
"nombre": "fichero4"
}
}
}
但是当我使用“marcado_ce”时:null:
{
"pdca_restbundle_prueba": {
"nombre": "nombre prueba2",
"marcado_ce": null
}
}
此消息失败:
{
"code": 400,
"message": "Validation Failed",
"errors": {
"errors": [
"Este valor no es valido."
],
"children": {
"nombre": {},
"marcado_ce": {
"children": {
"nombre": {}
}
}
}
}
}
调试此问题,这里是代码启动异常导致验证失败的地方:File Form.php,第570行:
if ($this->config->getCompound()) {
if (null === $submittedData) {
$submittedData = array();
}
if (!is_array($submittedData)) {
**throw new TransformationFailedException('Compound forms expect an array or NULL on submission.');**
}
我在这里上传了一个带有堆栈跟踪的图像:https://i.stack.imgur.com/QzPDc.png
我用这个编辑了Form.php代码替换异常代码(第750行) . 但这不是解决方案 . 我将尝试理解根本原因是什么,也许我会想念symfony-forms .
if (!is_array($submittedData)) {
$submittedData = array();
}