我是Golang和Gin框架的新手,我创建了两个模型
type Product struct {
gorm.Model
Name string
Media []Media
}
type Media struct {
gorm.Model
URI string
ProductID uint
}
和我发送一个POST请求来保存一个新产品,主体是:
{
"name": "Product1",
"media": [
"https://server.com/image1",
"https://server.com/image2",
"https://server.com/image3",
"https://server.com/video1",
"https://server.com/video2"
]
}
我用这个代码
保存一个新产品product := Product{}
if err := context.ShouldBindJSON(product); err != nil { // <-- here the error
context.String(http.StatusBadRequest, fmt.Sprintf("err: %s", err.Error()))
return
}
tx := DB.Create(&product)
if tx.Error != nil {
context.String(http.StatusBadRequest, fmt.Sprintf("err: %s", tx.Error))
return
}
返回的错误信息是
err: json: cannot unmarshal string into Go struct field Product.Media of type models.Media
我知道ShouldBindJSON
不能将media-string
转换为media-object
,但是这样做的最佳实践是什么?
有效负载与模型不匹配。在JSON主体中,media
是一个字符串数组,而在模型中,它是一个具有两个字段和嵌入式表单模型的结构体。
如果你不能改变你当前的设置,在Media
上实现UnmarshalJSON
,并从原始字节设置URI
字段。在同样的方法中,你也可以初始化ProductID
为一些东西(如果需要的话)。
func (m *Media) UnmarshalJSON(b []byte) error {
m.URI = string(b)
return nil
}
那么绑定将按预期工作:
product := Product{}
// pass a pointer to product
if err := context.ShouldBindJSON(&product); err != nil {
// handle err ...
return
}
fmt.Println(product) // {Product1 [{"https://server.com/image1" 0} ... }