Symfony表单验证失败 - "此表单不应包含额外字段"

时间:2017-10-05 13:57:13

标签: php symfony symfony-forms

我在前端使用React将数据发送到使用Symfony Form进行验证的控制器。从React发送的信息是我所期望的,但是我收到的错误是"此表单不应包含额外的字段"。

我想使用此表单创建一个新的预订,该表单有预订。预订有很多(或没有)reservationTripAddOns(TripAddOns)。我已经发现当我选择我想要链接到预订的旅行添加((TripAddOn :: class)reservationTripAddOn)时会引起问题。当我没有选择任何添加时,它可以工作。

当没有选择添加项时,从React传递的数据有效:

{
    "reservations”:
        [
            {
                "trip":277,
                "date":"10/27/2017”,
                "guests":2,
                "reservationTripAddOns":[]
            }
        ]
}

选择添加时,从React传递的数据不起作用:

{
    "reservations”:
        [
            {
                "trip":277,
                "date":"10/26/2017”,
                "guests":2,
                "reservationTripAddOns”:
                    [
                        {
                            "id":34,
                            "name":"Additional one guest”,
                            "price":100,
                            "trip”:null
                        }
                    ]
               }
        ]
}

BookingController:

    public function newAction(Request $request, GuideProfile $guideProfile)
    {
        $reservation = new Reservation();
        $booking = new Booking();
        $booking->addReservation($reservation);

        $form = $this->createForm(BookingType::class, $booking, ['guide_profile' => $guideProfile]);
        $form->submit(json_decode($request->getContent(), true));

        if ($form->isValid()) {
            $context = new SerializationContext();
            $context->setSerializeNull(true);
            $context->setGroups(['Session']);
            $this->get('session')->set(
                'booking', $this->get('serializer')->serialize($booking, 'json', $context)
            );

            return $this->createApiResponse($booking, ['Default'], 201);
        }

        return $this->createApiErrorResponse($form->getErrors(true));
    }

BookingType:

class BookingType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('reservations', CollectionType::class, [
            'entry_type' => ReservationType::class,
            'entry_options' => [
                'data_class' => Reservation::class,
                'guide_profile' => $options['guide_profile'],
            ],
            'allow_add' => true,
        ])
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Booking::class,
        'guide_profile' => null,
    ]);
}

}

ReservationType:

class ReservationType extends AbstractType
{
public function __construct(EntityManager $entityManager)
{
    $this->entityManager = $entityManager;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $guideProfileId = $options['guide_profile'] instanceof GuideProfile ? $options['guide_profile']->getId() : 0;

    $builder
        ->add('trip', EntityType::class, [
            'class' => Trip::class,
            'query_builder' => function (EntityRepository $er) use ($guideProfileId) {
                return $er->createQueryBuilder('t')
                    ->where('t.guideProfile = :guide_profile_id')
                    ->orderBy('t.title', 'ASC')
                    ->setParameter('guide_profile_id', $guideProfileId);
            },
            'choice_label' => 'title',
            'placeholder' => 'Select a Trip',
        ])
        ->add('date', DateType::class, [
            'format' => 'MM/dd/yyyy',
            'html5' => false,
            'widget' => 'single_text',
        ])
        ->add('reservationTripAddOns', 'collection', [
            'entry_type' => TripAddOnType::class,
            'entry_options' => [
                'data_class' => TripAddOn::class,
                'mapped' => false,
            ]
        ])
        ->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'addGuests'])
        ;
}

public function addGuests(FormEvent $event)
{
    //assume everything works here
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Reservation::class,
        'guide_profile' => null,
    ]);
}

TripAddOnType:

class TripAddOnType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('price', TextType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\TripAddOn'
        ]);
    }

0 个答案:

没有答案