使用Symfony 2表单验证API输入

使用Symfony 2表单验证API输入,symfony,symfony-2.1,fosrestbundle,Symfony,Symfony 2.1,Fosrestbundle,我正在使用Symfony2、条令和FOSRestBundle构建一个API。我想使用表单组件来验证创建或修改记录的API请求,但我遇到了一些问题。我一直在单独使用验证组件,但希望使用表单组件,因为它将所有验证逻辑移出控制器,更好地处理将请求数据绑定到实体的问题,并更好地聚合错误消息 我遇到的问题与不需要的字段有关,无论是通过POST创建记录还是通过PUT更新记录。理想情况下,我希望不必通过HTTP提交非必填字段,但这会导致表单验证失败。例如,我正在使用的实体上的一个字段是名为endTime的Da

我正在使用Symfony2、条令和FOSRestBundle构建一个API。我想使用表单组件来验证创建或修改记录的API请求,但我遇到了一些问题。我一直在单独使用验证组件,但希望使用表单组件,因为它将所有验证逻辑移出控制器,更好地处理将请求数据绑定到实体的问题,并更好地聚合错误消息

我遇到的问题与不需要的字段有关,无论是通过POST创建记录还是通过PUT更新记录。理想情况下,我希望不必通过HTTP提交非必填字段,但这会导致表单验证失败。例如,我正在使用的实体上的一个字段是名为endTime的DateTime字段,这不是必需的。如果POST或PUT请求中不存在名为endTime的参数,Symfony2将请求中的值null绑定到字段。当它转换为DateTime实例时,它被转换为当前日期时间,这根本不是我想要的

如果HTTP请求中不存在值,有没有办法告诉Symfony不要将值绑定到实体?这应该仍然是安全的,因为基于实体类中的注释的验证仍然会失败。我可以重写bind方法,但这似乎需要做很多工作


谢谢您的建议。

创建一个数组,将非必填字段作为键,然后合并您的请求POST或放在该数组的顶部,并将其绑定到表单。这样,表单就有了提示必填字段,并且如果提供了请求数据,就会有请求数据

您可以创建一个表单EventSubscriber,该表单在
预绑定
事件上,将未提交的字段替换为其默认值(即被绑定对象的值),而不是null

以下是我创建的订阅服务器:。 默认情况下,在我的实现中,只有非必填字段才具有默认值,而不是null


您和任何人都可以自由使用这个类,只要您保留author标记,实际上;-)

您可以使用和的组合来实现这一点

首先,创建表单(
Your\Bundle\form\CreateFormType
),它扩展了
Symfony\Component\form\AbstractType
中的相应元素来构建表单:

$builder ->add('title') ->add('firstNames');
我使用同样的方法,而且它工作得非常完美:如果不在表单生成器中添加字段,它就完全没有绑定。我没有使用表单生成器,而是创建了一个单独的表单类。这应该允许我使用NelmioAPIDocBundle中的表单自动生成文档。看起来,根据提交的内容从表单中删除元素可能是一种方式……这样的捆绑包考虑使用您自己的
FormType
s,[
input=“your\Namespace\form\Type\YourType”
]-只是不要在
buildForm()
method.moonwave99中添加不需要的字段-没有那么简单。POST请求(创建资源)需要一些字段,这些字段随后成为PUT请求(更新资源)的可选字段。其他两个解决方案中的任何一个都会更好…这看起来是一个可能的解决方案。我可以将提交的参数与表单字段进行比较,并删除所有尚未提交的表单字段。验证应该保持完整,因为它与表单是分开的。我会在星期一给大家介绍一下:谢谢!谢谢,这个主意很管用。我使用了AdrienBrault关于事件监听器的想法,但根据您建议的提交内容,使用代码删除表单元素。再次感谢。这是另一个很好的解决方案。我可以编辑代码以使用事件侦听器,但可以从表单中删除任何未提交的字段。这样,数据将不会绑定到实体,但验证仍将根据实体中的注释通过/失败。谢谢你的想法和代码!我相信这是一条路,事件聆听者。虽然它可能很复杂,但最终可能是最干净的解决方案。我希望我也能将您的答案标记为解决方案,因为我按照您的建议使用了事件订阅服务器,但DrFrow的想法是根据提交的内容删除表单元素。你也提供了一大块答案。:)如果以后需要呈现表单的某些视图,删除未提交其值的表单元素将给您带来麻烦。(在我的例子中,作为回报,表单的xml/json表示形式)在我的例子中不应该是问题。我正在使用FOSRestBundle,如果验证失败,则从控制器返回表单。FOSRestBundle处理设置400响应和收集表单中的错误。由于验证与表单是分开的,因此如果从表单中删除元素,似乎不会导致任何问题,但仍会显示正确的错误。你知道实现这一目标的另一种方法吗?有没有办法告诉表单不要处理尚未提交的元素? Your\Bundle\Entity\User: properties: title: - NotBlank: groups: [register] message: Please provide your title firstNames: - NotBlank: groups: [register] message: Please provide your first name(s) $resolver->setDefaults(array( // ... 'validation_groups' => array('register'), // ... ));