Bind()
is great, but what do you guys think if it supports default values when a param is not specified? Something like this:
params = struct {
Name string `form:"name,default=john"`
Age uint `form:"address,default=10"`
}{}
c.Bind(¶m)
Comment From: thinkerou
Hi @atedja I have commit one pull request and I attempt to complete it.
Comment From: thinkerou
@atedja Now the pr have merged to the master branch.
Comment From: appleboy
Implement in #1138 . try it in the latest master branch.
Comment From: calixwu
So, how to use it???
Comment From: KingJeason
So, how to use it ???
Comment From: to2false
@KingJeason @calixwu
`form:"field_name,default=value"`
It worked for me.
Comment From: calixwu
@to2false I have already used it that way, but thanks all the same. I think it's better to document this usage.
Comment From: SnowOnion
Another story. For those who, like me, want default JSON field value when using BindJSON
:
Just set the default value when initializing the struct
. E.g.
params = struct {
Name string `json:"name"`
Age uint `json:"address"`
}{
Name: "john",
Age: 10,
}
c.BindJSON(¶ms)
And from this issue I got to know anonymous struct.
I learnt a lot today.
Comment From: Gera-coder
Another story. For those who, like me, want default JSON field value when using
BindJSON
: Just set the default value when initializing thestruct
. E.g.
go params = struct { Name string `json:"name"` Age uint `json:"address"` }{ Name: "john", Age: 10, } c.BindJSON(¶ms)
And from this issue I got to know anonymous struct.
I learnt a lot today.
Hi Snow, I tried your way but it can only work with field missing.
For example, if you passed in a json string with age
set to init value zero, 10 would got replaced.
Comment From: kamly
@thinkerou @SnowOnion @Gera-coder
I want to wirte this
type Param struct {
Name string `json:"name,default=john"`
Age uint `json:"address,default=10"`
}
var param Param
c.ShouldBind(¶m)
but it doesn't work, has any good method in ShouldBind JSON?
Comment From: runzhliu
I think the default value doesn't work for the json
type, actually, I find no related unitest for the default value except for the form
type, but assigning the default value before the binding works for me.
Comment From: kangour
if use dive then default invalid, help.
Comment From: olivatooo
help :pensive:
Comment From: AuroraTea
@KingJeason @calixwu
`form:"field_name,default=value"`
It worked for me.
Sorry for Interrupting you, is it now discarded?
type ReqListUsers struct {
Limit int64 `form:"limit,default=20" binding:"min=1,max=100"`
Sort string `form:"sort,default=id" binding:"omitempty,oneof=id createAt lastLoginAt"`
Order string `form:"order,default=asc" binding:"omitempty,oneof=asc desc"`
}
func ListUsers(c *gin.Context) {
var req ReqListUsers
err := c.ShouldBindQuery(&req)
But not work.
Comment From: hexuan1922
@thinkerou @SnowOnion @Gera-coder
I want to wirte this
go type Param struct { Name string `json:"name,default=john"` Age uint `json:"address,default=10"` } var param Param c.ShouldBind(¶m)
but it doesn't work, has any good method in ShouldBind JSON?
type User struct {
Name string `form:"name,default=user1" json:"name,default=user2"`
Age int `form:"age,default=10" json:"age,default=20"`
}
r := gin.Default()
// way1 curl 127.0.0.1:8900/bind?name=aa
// way2 curl -X POST 127.0.0.1:8900/bind -d "name=aa&age=30"
// way3 curl -X POST 127.0.0.1:8900/bind -H "Content-Type: application/json" -d "{\"name\": \"aa\"}"
r.Any("/bind", func(c *gin.Context) {
var user User
//user = User{Name: "bb", Age: 11} //way4:A variable of type User can be generated with the default value before bind
if c.ContentType() == binding.MIMEJSON {
//way5:A variable of type User can be generated with the default value before bind.
_ = binding.MapFormWithTag(&user, nil, "json")
}
_ = c.Bind(&user) //Note that because bind is used here to request json, you specify the Content-Type header
c.String(200, "Hello %v age %v", user.Name, user.Age)
})
// The above 4 way.
// way1/2 structTag is work.because gin at queryBinding/formBinding execute mapFormByTag logic, will check formTag
// way3 structTag not work. gin at jsonBinding non-execution mapFormByTag logic
// way4/way5 no matter query/form/json All valid
// way5 is work. Because the mapFormByTag logic is triggered in addition
r.Run(":8900")
good luck. @kamly
Comment From: kangour
楼上通过 _ = binding.MapFormWithTag(&user, nil, "json") 修改参数的解析 tag,对我有效,感谢分享。
Comment From: cylonchau
@hexuan1922
I use github.com/gin-gonic/gin v1.10.0
and use your example, but following code don't work, just can work on single struct.
type Target struct {
metav1.TypeMeta
Targets []TargetItem `form:"targets" json:"targets"`
InstanceSelector map[string]string `json:"instanceSelector"`
}
type TargetItem struct {
Address string `form:"address" json:"address" yaml:"address" binding:"required"`
MetricPath string `form:"metric_path,default=/metrics" json:"metric_path,default=/metrics" yaml:"metric_path"`
ScrapeTime int `form:"scrap_time,default=30" json:"scrape_time,default=30" yaml:"scrap_time" `
ScrapeTimeout int `form:"scrape_timeout,default=10" json:"scrape_timeout,default=10" yaml:"scrap_timeout"`
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty" form:"labels,omitempty"`
}
var enconterError error
targetQuery := &target.Target{}
_ := binding.MapFormWithTag(&targetQuery, nil, "json")
if enconterError = c.Bind(&targetQuery); enconterError != nil {
query.API500Response(c, enconterError)
return
}
fmt.Println(targetQuery)
targetQuery.Targets is a list, and inital, it is a nil, the targetQuery don't kown amount of targetQuery.Targets, so this code don't work.
if execute MapFormWithTag() after execute Bind(), then value will be overwrite with default tag, despite passing in a value instead of using the default.
Comment From: cylonchau
楼上通过 _ = binding.MapFormWithTag(&user, nil, "json") 修改参数的解析 tag,对我有效,感谢分享。
这种方式只是在初始化这个结构体时,手动映射一下tag,然后再Bind时,如果传入了参数会被重写,没有传入就使用默认值了,这种情况只能是使用非列表类型时生效,如果你的参数结构体使用了列表类型,初始binding.MapFormWithTag不知道列表数量,他不会进行重写,而且嵌套格式通常无法指定tag,所以这种方式不会应用子结构体中的tag或者列表中的tag
Comment From: AtariOverlord09
@KingJeason @calixwu
`form:"field_name,default=value"`
It worked for me.
Sorry for Interrupting you, is it now discarded?
``go type ReqListUsers struct { Limit int64
form:"limit,default=20" binding:"min=1,max=100"Sort string
form:"sort,default=id" binding:"omitempty,oneof=id createAt lastLoginAt"Order string
form:"order,default=asc" binding:"omitempty,oneof=asc desc"` }func ListUsers(c *gin.Context) { var req ReqListUsers err := c.ShouldBindQuery(&req) ```
But not work.
how did you fix it?