- gin version (or commit ref): 1.3.0
- operating system: Linux
Description
How does the function BindQuery bind the array?
type DeleteQueryParam struct {
UserName int form:"name" binding:"required"
ttl string form:"ttl" binding:"required"
Id []int form:"id" binding:"required"
}
param id
can't bind the array correctly
Comment From: thinkerou
@younglifestyle please see #653 issue BTW, you should search issue or pull request when answer question before. thanks!
Comment From: swrap
Gin version: v1.4.0 OS: Linux
@thinkerou referenced both #653 and #570. Maybe I am doing something wrong, but there are no concrete examples anywhere.
Description
Make a request with an array of form values will be parsed correctly as a list.
Replication
Request: https://www.example.com/publish?ids[]=16&ids[]=18&isPublished=true
Gin Backend:
func checkIfPublished(c *gin.Context) {
type queryHolder struct {
IsPublished bool `form:"isPublished" binding:"exists"`
Ids []uint `form:"ids[]" binding:"required"`
}
var qholder queryHolder
if err := c.ShouldBindQuery(&qholder); err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
log.Printf("%+v\n", qholder)
}
Output:
2019/10/20 16:09:34 {IsPublished:true Ids:[18]}
Expected Output
2019/10/20 16:09:34 {IsPublished:true Ids:[16,18]}
Comment From: vkd
For me everything is ok:
2019/10/20 21:11:47 {IsPublished:true Ids:[16 18]}
[GIN] 2019/10/20 - 21:11:47 | 200 | 433.233µs | ::1 | GET /hello?ids[]=16&ids[]=18&isPublished=true
curl -i "http://localhost:9000/hello?ids\[\]=16&ids\[\]=18&isPublished=true"
HTTP/1.1 200 OK
Comment From: swrap
For me everything is ok:
2019/10/20 21:11:47 {IsPublished:true Ids:[16 18]} [GIN] 2019/10/20 - 21:11:47 | 200 | 433.233µs | ::1 | GET /hello?ids[]=16&ids[]=18&isPublished=true
curl -i "http://localhost:9000/hello?ids\[\]=16&ids\[\]=18&isPublished=true" HTTP/1.1 200 OK
@vkd You were completely right so sorry about this. It was because I had my endpoint behind AWS gateway, which it does not support duplicates.
Comment From: breemts
Does anyone have an idea what the struct tag syntax for this array format could look like? Because this call is not working:
curl -i "http://localhost:9000/hello?ids=16,18&isPublished=true"
Also the following request does not result in an error, but should in my opinion:
curl -i "http://localhost:9000/hello?isPublished=true&ids\[\]="
will result in the output: {IsPublished:true Ids:[0]}
Comment From: louis77
AFAIK Gin doesn't support binding of comma-separated values into slices. But you can build your own type:
type CSIntList string
func (c CSIntList) Values() []int {
res := []int{}
str := string(c)
if len(str) > 0 {
values := strings.Split(str, ",")
for _, v := range values {
if i, err := strconv.Atoi(v); err == nil {
res = append(res, i)
}
}
}
if len(res) == 0 {
return nil
}
return res
}
type queryHolder struct {
IsPublished bool `form:"isPublished" binding:"exists"`
Ids CSIntList `form:"ids" binding:"required"`
}
...
... := gin.Bind(&query)
ids := query.Ids.Values()
...