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?