How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "net/http"
)

type QueryModel struct {
    Id *primitive.ObjectID `form:"id"`
}

func main() {
    g := gin.Default()

    g.GET("/hello/", func(c *gin.Context) {
        var query QueryModel
        if err := c.BindQuery(&query); err != nil {
            c.JSON(http.StatusBadRequest, bson.M{"msg": err.Error()})
            return
        }
    })
    g.Run(":9000")
}

Actual result

$ curl http://localhost:9000/hello/\?id\=5f2146e27d0e10f02a525412
{"msg":"[\"5f2146e27d0e10f02a525412\"] is not valid value for primitive.ObjectID"}%

Comment From: uzayr

Works as

type QueryModel struct {
    T *time.Time `form:"t"`
}

However, not with primitive.ObjectID.

Nevertheless, if i write it as

type JSONModel struct {
    Id *primitive.ObjectID `json:"id"`
}

try to bind with BindJSON it works though.

Comment From: RayChenCode

Same issue here, is it any possible convert string value to primitive.ObjectID value via c.ShouldBindQuery function?

Comment From: Admingyu

Same issue here

Comment From: leoblum

+1

Comment From: DoQuocHoang

use :

type QueryModel struct {
    Id *string `form:"id"`
}

then

g.GET("/hello/", func(c *gin.Context) {
        var query QueryModel
        if err := c.BindQuery(&query); err != nil {
            c.JSON(http.StatusBadRequest, bson.M{"msg": err.Error()})
            return
        }

                modelId, err := primitive.ObjectIDFromHex(query.Id)
                if err != nil {
                // do sth...
                }
})

now you have modelId is primitive.ObjectID type

Comment From: hunjixin

same to, not only ObjectId but cid, anything represent as string

Comment From: tinncdev

I ended up separating controller DTO (use string) and service DTO (use primitive.ObjectID).

The controller layer always receive raw types like string from request, parsing to service DTO, returned BadRequest if needed.

This would be better If there's some way to write a custom binding for custom type, similar to custom validator?