Symfony验证组中NotBlank与Type断言异常问题问询
验证组配置异常问题解析
我在尝试将number值添加到Counter类的sum属性时遇到了验证组相关的异常:
- 为
@Assert\NotBlank指定groups={"add"}时,该断言完全无效;移除groups参数后,断言才正常生效。 - 相反,
@Assert\Type指定groups={"add"}时可正常工作;移除groups参数则会抛出验证异常。
相关代码
Counter类
/** * @ORM\Entity() * ... * @ApiResource( * attributes={"maximum_items_per_page"=50}, * messenger="input", * shortName="Counters", * collectionOperations={}, * itemOperations={ * "remove_inventory_item"={ * "method"="PUT", * "path"="/counter/{id}/add", * "input"=CounterInput::class, * "normalization_context"={"groups"={"Default", "add"}}, * "denormalization_context"={"groups"={"Default", "add"}}, * }, * ... * } * ) */ class Counter { /** * @ORM\Column(type="integer", length=255) */ private int $sum = 0; ... }
CounterInput类
class CounterInput { ... /** * @var int * * @ApiProperty( * attributes={ * "swagger_context"={ * "type"="integer" * } * } * ) * * @Assert\NotBlank * @Assert\Type(type="int", groups={"add"}) * * @Groups({"add"}) */ public $number; ... }
异常信息(移除Type断言的groups参数后)
{ "type": "https://tools.ietf.org/html/rfc2616#section-10", "title": "An error occurred", "detail": "Message of type \"App\\CounterInput\" failed validation.", "trace": [ { "namespace": "", "short_class": "", "class": "", "type": "", "function": "", "file": "/srv/vendor/symfony/messenger/Middleware/ValidationMiddleware.php", "line": 45, "args": [] }, ... }
问题解析与解决方法
核心原因:序列化组≠验证组
你混淆了序列化组和验证组的作用:
denormalization_context中的groups是给Symfony序列化器用的,仅控制哪些属性被反序列化到对象中,和验证流程无关;- Symfony验证器(包括Messenger的
ValidationMiddleware)默认只会验证标记为Default组的断言,不会自动继承序列化组的配置。
逐个解释现象
1. NotBlank断言加groups={"add"}无效
- 未指定
groups时,@Assert\NotBlank默认属于Default验证组,而ValidationMiddleware默认验证Default组,所以空值会被拦截; - 加上
groups={"add"}后,该断言仅属于add组,但你的验证流程未启用add组,所以断言不会被触发,空值可通过。
2. Type断言加groups={"add"}正常,不加则报错
- 指定
groups={"add"}时,该断言仅属于add组,验证流程未启用该组,所以断言不会执行,即使传入非int值也不会触发验证; - 移除
groups后,断言默认属于Default组,ValidationMiddleware会验证它,若传入值类型不符合则抛出异常。
解决方法
在@ApiResource配置中添加validation_groups,指定验证流程要使用的组:
// Counter类的@ApiResource配置中补充 @ApiResource( // ... 原有配置 validation_groups={"Default", "add"}, // ... 原有配置 )
这样ValidationMiddleware会同时验证Default和add组的断言,两个验证规则都会正常生效。
内容的提问来源于stack exchange,提问作者MiraTech
相关产品推荐
相关产品推荐

