我正在使用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时,它按预期工作:
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;
}
}
但我想发送一个null(编辑实体并使用可选的Archivo创建新实体):
{ "pdca_restbundle_documentacion": { "maquina": 752, "declaracion_conformidad": { "nombre": "fichero10" } }
这是我发送空值时的验证错误:
此值无效。
在我的控制器中:
{ "pdca_restbundle_documentacion": { "maquina": 752, "declaracion_conformidad": null }
任何帮助将不胜感激。
编辑#1 我创建了一个简单的实体,没有继承用于测试,但结果相同。
实体Prueba:
$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); }
实体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": {}
}
}
}
}
}
调试此问题,这里是代码启动异常导致验证失败的地方: 文件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代码,用此代替Exception代码(第750行)。但这不是解决方案。我将尝试了解什么是根本原因,也许我会错过symfony-forms的内容。
if (!is_array($submittedData)) {
$submittedData = array();
}