关于 gin 的 Context.ShouldBind 对结构体 tag `binding:"required"` 校验失效问题(缺失字段未报错)
1. 运行环境
go1.19.13 windows/amd64
github.com/gin-gonic/gin v1.9.0
2. 问题描述?
Context.ShouldBind 对结构体 tag binding:"required"
校验失效:缺失字段未报错
示例代码:
// package form
type UpdateRequest2 struct {
Sdagfadgasasdgsafdfsdafs string `form:"sdagfadgasasdgsafdfsdafs" binding:"required"`
}
// package api
func (Analysis) Update(ctx *gin.Context) {
fmt.Println("================Update===========")
params := &form.UpdateRequest2{}
errA := ctx.ShouldBind(params)
fmt.Println("bindA: ", errA)
errB := ctx.ShouldBind(¶ms)
fmt.Println("bindB: ", errB)
errC := ctx.ShouldBind(*params)
fmt.Println("bindC: ", errC)
fmt.Println(ctx.Request.Form)
}
通过 postman 进行PUT测试 form-data 等数据均留空,结果如下:
================Update===========
bindA: Key: 'UpdateRequest2.Sdagfadgasasdgsafdfsdafs' Error:Field validation for 'Sdagfadgasasdgsafdfsdafs' failed on the 'required' tag
bindB: <nil>
bindC: Key: 'UpdateRequest2.Sdagfadgasasdgsafdfsdafs' Error:Field validation for 'Sdagfadgasasdgsafdfsdafs' failed on the 'required' tag
map[]
如上所示当 ShouldBind 的参数是 结构体指针的指针就无法正确校验,传的是结构体和其指针就正常。好奇就看了下源码,但感觉应该不会如此(最终都会还原成结构体来校验),所以写了一个测试用例
func TestBind2(t *testing.T) {
ctx, _ := gin.CreateTestContext(httptest.NewRecorder())
ctx.Request = httptest.NewRequest("PUT", "http://127.0.0.1:8003/test", nil)
params := &form.UpdateRequest2{}
errA := ctx.ShouldBind(params)
fmt.Println("bindA: ", errA)
errB := ctx.ShouldBind(¶ms)
fmt.Println("bindB: ", errB)
errC := ctx.ShouldBind(*params)
fmt.Println("bindC: ", errC)
fmt.Println(ctx.Request.Form)
}
结果如下
bindA: Key: 'UpdateRequest2.Sdagfadgasasdgsafdfsdafs' Error:Field validation for 'Sdagfadgasasdgsafdfsdafs' failed on the 'required' tag
bindB: Key: 'UpdateRequest2.Sdagfadgasasdgsafdfsdafs' Error:Field validation for 'Sdagfadgasasdgsafdfsdafs' failed on the 'required' tag
bindC: Key: 'UpdateRequest2.Sdagfadgasasdgsafdfsdafs' Error:Field validation for 'Sdagfadgasasdgsafdfsdafs' failed on the 'required' tag
map[]
两次测试 ctx.Request.Form 都是空的
测试用例中三种情况都能够正常进行校验,不理解为什么会造成这种差异。
是否有其他地方影响了 ShouldBind 的校验?
3.目标
找到造成两种情况结果不同的原因。
问题找到了,项目里面的代码修改了验证器,而那个自定义的验证器没有递归的处理
obj
导致多层指针的情况下没有成功验证 :see_no_evil: