如何让Symfony表单与REST API一起使用?

Der*_*k F 6 symfony-forms symfony symfony-2.3

我目前正在尝试使用symfony表单来处理我的帖子并放入rest api端点.

目前我有:

$request = $this->getRequest();
$cc = new CreditCard();
$form = $this->createForm(new CreditCardType(), $cc);

$form->handleRequest($request);

if ($form->isValid()) {
  //...
}
Run Code Online (Sandbox Code Playgroud)

但是,表单永远不会有效.查看问题,似乎表单的isSubmitted字段为false,因此它永远不会通过验证.此外,由于这是一个api调用,我在creditcardtype中将csrf_protection设置为false.

以下是我向用户提交的数据的示例:

{
  "credit_card": {
     "name" : "Example Name"
     ...
  }
}
Run Code Online (Sandbox Code Playgroud)

如何将此post/put请求注册为已提交并且表单验证者通过?谢谢.

Gui*_*itz 10

如果您可以提供CreditCardType类的完整代码以及表单中的完整POST数据和验证错误,将会很有帮助.

无论如何,这是我发现表单提交失败的原因:

  • 提交不完整的数据:如果您的POST请求中没有CerditCardType表单上的字段,请确保将"required"选项设置为false.
  • 表单名称:确保所有字段都由以表单名称命名的属性(您在CreditCardType :: getName()方法中提供的名称)包装.在你的情况下,我认为这是"credit_card".
  • 仅发布您的CreditCardType类中定义的字段.如果您发布的参数与表单的任何字段都不匹配,您将收到验证错误,例如"此表单不应包含任何额外字段"或类似内容.

无论如何,如果您提供更多信息,我会很乐意提供更多帮助.

更新:

好吧,我觉得你的问题是你要发送的数据作为JSON字符串,该handleRequest()方法没有得到任何数据,因为Symfony的不知道应该从请求体解码(预计要发送的数据无论是作为$ _GET或$ _POST参数).所以你必须自己做.

handleRequest()您不必使用该submit()方法,而是将方法与通过解码请求内容($request->getContent())获得的数据一起使用:

$request = $this->getRequest();
$cc = new CreditCard();
$form = $this->createForm(new CreditCardType(), $cc);

// Decode de JSON input
$data = json_decode($request->getContent(), true);

// Post the data to the form
$form->submit($data);

if ($form->isValid()) {
  //...
}
Run Code Online (Sandbox Code Playgroud)

希望现在有所帮助!

顺便说一句,如果你正在使用RESTful实现,你应该考虑使用FOSRestBundle包.它将为您处理所有格式转换逻辑以及路由,实体de /序列化等.


qoo*_*mao 5

您的数据未正确传递到表单,因为您传入的请求对象没有表单名称作为键.

当您使用Symfony创建表单时,它会在创建时创建以下类型的数组POST.

"your_form_name": {         // Given that you forms `getName()` 
                            // returns "your_form_name"
    "field1": "value1",
    "field2": "value2"
}
Run Code Online (Sandbox Code Playgroud)

当您使用该handleRequest方法时,它使用表单名称作为键,如下所示(有关完整代码,请参阅github).

if ('GET' === $method) {
        if ('' === $name) {
            $data = $_GET;
        } else {
            // Don't submit GET requests if the form's name does not exist
            // in the request
            if (!isset($_GET[$name])) {
                return;
            }

            $data = $_GET[$name];
        }
    } else {
        // ... same sort of stuff for $_POST, $_FILES, etc
    }

    // ...

    $form->submit($data, 'PATCH' !== $method);
Run Code Online (Sandbox Code Playgroud)

这意味着如果您提交的数组不包含表单名称,则不会提交.

解决这个问题的submit()方法是使用该方法代替并提交所有数据而不是表单名称密钥的数据,如...

$form->submit($request->request->all());    // $_POST

$form->submit($request->query->all());      // $_GET
Run Code Online (Sandbox Code Playgroud)