// trace info
type TraceInfo struct{
    Id_ bson.ObjectId `form:"_id" json:"_id" bson:"_id"` 
    Search SearchInfo `form:"search" json:"search" bson:"search"`
}

// search
type SearchInfo struct{
    Text string `form:"text" json:"text" bson:"text"`
    ResultQty string `form:"result_qty" json:"result_qty" bson:"result_qty"`
}

func SaveJsData(c *gin.Context){
    var traceInfo TraceInfo
    err := c.ShouldBindQuery(&traceInfo);
    if err != nil {
        c.AbortWithStatusJSON(http.StatusOK, util.BuildFailResult(err.Error()))
        return
    }
}

when i access http://xxxx:3000/fec/trace?search[text]=dress&search[result_qty]=13

can not get this search param,empty:

 "search": {
     "text": "",
     "result_qty": "" 
  } 

Comment From: sosedoff

AFAIK, Go does not support nested form parameters like it does with JSON/XML. This is due to the form/query object simply being a map[string][]string. So if you run the example below, you'll see what i'm talking about.

package main

import (
    "github.com/gin-gonic/gin"
)

func handler(c *gin.Context) {
    if err := c.Request.ParseForm(); err != nil {
        c.AbortWithStatusJSON(400, gin.H{"error": err.Error()})
        return
    }

    c.JSON(200, gin.H{
        "query": c.Request.URL.Query(),
        "form":  c.Request.Form,
    })
}

func main() {
    router := gin.Default()
    router.Any("/test", handler)
    router.Run(":5000")
}

Then in the browser visit http://localhost:5000/test?name=bob&info[foo]=bar. Example output:

{
  "form": {
    "info[foo]": [
      "bar"
    ],
    "name": [
      "bob"
    ]
  },
  "query": {
    "info[foo]": [
      "bar"
    ],
    "name": [
      "bob"
    ]
  }
}

Comment From: thinkerou

@fancyecommerce please see https://github.com/gin-gonic/gin#bind-form-data-request-with-custom-struct, maybe it can help you.

Comment From: andreacab

I am having a similar issue where ShouldBindQuery does not seem to recognize the "comma pattern" in the query part of the url such as ?genre=jazz,blues.

Gin version: 1.6.3

For example, if I request the following

$ curl http://localhost:8082/rest/v1/search\?genre\=jazz,blues

with the following code

type searchQuery struct {
    Genre                 []string `form:"genre"`
}

func searchHandler(c *gin.Context) {
         var query searchQuery
    if err := c.ShouldBindQuery(&query); err != nil {
        log.Fatal(err)
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
        genre := c.Request.URL.Query()
        log.Printf("genre %v, length %d, searchQuery.Genre %v, length %d, type  %T", genre["genre"], len(genre["genre"]), query.Genre, len(query.Genre), query.Genre)
}

the app logs

// -> Genre [jazz,blues], length 1, searchQuery.Genre [jazz,blues], length 1, type []string

If I deduplicate the query params as in

$ curl http://localhost:8082/rest/v1/search\?genre\=jazz\&genre\=blues

the app logs

// -> Genre [jazz blues], length 2, searchQuery.Genre [jazz blues], length 2, type []string

and works. I am not sure what I am doing wrong, but it feels kinda odd.

Comment From: rexfordnyrk

hey I am facing same problem. were you able to resolve yours? having to duplicate query params doesn't look clean to me. comma separated values seem simple and cleaner. any pointers please? @thinkerou @appleboy

Comment From: yukal

Hey guys, it turns out to be easier than it seemed, see the example here:

type FilterData struct {
  RegionId uint8      `query:"regionId"`
  Phone    string     `query:"phone"`
}

type Filter struct {
  Data     FilterData `query:"data"`
}

type Payload struct {
  Filter   Filter     `query:"filter"`
}

func getAnnounce(c *gin.Context) {
  // ?filter[data][regionId]=1&filter[data][phone]=380001234567
  Url.UnmarshalQuery(c.Request.URL.Query(), &payload)
})

Comment From: katatrina

I am having a similar issue where ShouldBindQuery does not seem to recognize the "comma pattern" in the query part of the url such as ?genre=jazz,blues.

Gin version: 1.6.3

For example, if I request the following

$ curl http://localhost:8082/rest/v1/search\?genre\=jazz,blues

with the following code

`` type searchQuery struct { Genre []stringform:"genre"` }

func searchHandler(c *gin.Context) { var query searchQuery if err := c.ShouldBindQuery(&query); err != nil { log.Fatal(err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } genre := c.Request.URL.Query() log.Printf("genre %v, length %d, searchQuery.Genre %v, length %d, type %T", genre["genre"], len(genre["genre"]), query.Genre, len(query.Genre), query.Genre) } ```

the app logs

// -> Genre [jazz,blues], length 1, searchQuery.Genre [jazz,blues], length 1, type []string

If I deduplicate the query params as in

$ curl http://localhost:8082/rest/v1/search\?genre\=jazz\&genre\=blues

the app logs

// -> Genre [jazz blues], length 2, searchQuery.Genre [jazz blues], length 2, type []string

and works. I am not sure what I am doing wrong, but it feels kinda odd.

Seem this issue still exists. I wonder why the maintainers not address this.