Symfony2.4表单'此表单不应包含额外字段'错误

mmm*_*mmm 12 php forms symfony angularjs symfony-2.4

我正在尝试基于REST api ang AngularJS构建应用程序.我一直在关注这个教程http://npmasters.com/2012/11/25/Symfony2-Rest-FOSRestBundle.html但是必须更改一些细节(折旧方法),现在当我发布创建新实体时我得到了'此表单不应包含额外字段'错误.

class MainController extends Controller
{
    public function indexAction(Request $request)
    {
        $form = $this->createForm(new TaskType(),null,array('action' => $this->generateUrl('post_tasks').'.json'))
                ->add('submit','submit');


        $note_form = $this->createForm(new NoteType())
                ->add('submit','submit');

        return $this->render('MyBundle:Main:index.html.twig',
                array(
                    'form'=>$form->createView(),
                    'note_form'=>$note_form->createView(),
                )
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

我的TaskType表单:

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder

            ->add('timeStart','datetime',array(
                'date_widget' => 'single_text',
                'time_widget' => 'single_text',
                'date_format' => 'yyyy-MM-dd',
                'data' => new \DateTime('now')
            ))

            ->add('timeStop','datetime',array(
                'date_widget' => 'single_text',
                'time_widget' => 'single_text',
                'date_format' => 'yyyy-MM-dd',
                'data' => new \DateTime('now')
            ))

            ->add('project')  
            ->add('descriptionTask')
            ->add('isCompleted',null,array('required' => false))  
            ->add('isVisible',null,array('required' => false))
        ;
    }
Run Code Online (Sandbox Code Playgroud)

现在在我看来我只渲染一种形式,但正处于测试阶段:

{%extends 'MyBundle::layout.html.twig' %}

{%block content %}

<div ng-view></div>

{{ form(form) }}

{% endblock %}
Run Code Online (Sandbox Code Playgroud)

这是REST控制器,它应该刷新给定的实体:

public function cpostAction(Request $request)
{
 $entity = new Task();
 $form = $this->createForm(new TaskType(), $entity);
 $form->handleRequest($request);

 if ($form->isValid()) {

     $em = $this->getDoctrine()->getManager();
     $em->persist($entity);
     $em->flush();

     return $this->redirectView(
             $this->generateUrl(
                 'get_organisation',
                 array('id' => $entity->getId())
                 ),
             Codes::HTTP_CREATED
             );
 }

 return array(
     'form' => $form,
 );
}
Run Code Online (Sandbox Code Playgroud)

WEIRD THING:当我将相同的代码从REST控制器放到MainController时,然后表单被验证并刷新新实体,但不知何故REST控制器抛出错误...

小智 26

如果您希望验证器忽略其他字段,您应该尝试将其'allow_extra_fields' => true作为选项传递给FormBuilder.

  • 注意:Symfony v2.6中添加了`allow_extra_fields`选项 (7认同)

Cha*_*ase 17

这是因为当您生成表单时,您正在添加提交按钮,但是当您验证它们时,您不是.尝试:

public function cpostAction(Request $request)
{
    $entity = new Task();
    $form = $this->createForm(new TaskType(), $entity)->add('submit','submit');
    ...
Run Code Online (Sandbox Code Playgroud)

提交按钮在技术上是一个字段,即使symfony默认情况下不会将其映射到实体属性.因此,当您使用提交按钮生成表单然后提交该表单时,您在验证控制器中生成的表单操作也需要一个提交按钮.


小智 5

如果您想禁用字段验证,则必须添加

public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'csrf_protection' => false,
        'validation_groups' => false,
    ));
}
Run Code Online (Sandbox Code Playgroud)

在 buildForm 方法中:

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->addEventListener(FormEvents::POST_SUBMIT, function ($event) {
            $event->stopPropagation();
        }, 900);
        $builder->add('field1','text')
                ->add('field2','text')
                .
                .
                .
    } 
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-dynamic-form-modification-suppressing-form-validation

  • 请记住,禁用 csrf 是一种非常非常糟糕的安全做法。很可能总有更好的方法来解决问题。 (6认同)
  • @csvan 但也不适用于 Restful API (3认同)

Dev*_*vWL 5

在 Symfony 4/5 中使用 CustomFormType 工作

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => CustomFormType::class,
        'allow_extra_fields' => true // <<<<<<<<<<<<<<<<<<<<<
    ]);
}
Run Code Online (Sandbox Code Playgroud)