-
Notifications
You must be signed in to change notification settings - Fork 544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BindAndValidate BindForm解析时间字符串为空 #1123
Comments
现在先用json 来规避吧 |
我测试了下,如果你的 "MyTime已经重写UnmarshalJSON解析字符串" 是会正常进行参数绑定的;如果你稳定复现的话,可以粘贴一个具体的单测例子。 以下是我的测试 case
|
我测试了一下,在使用复杂的自定义类型时,像time.Time,需要明确知道如何将请求参数(如字符串)转换为目标类型。就需要设置自定义的BindConfig,并注册自定义解码器。这样子就可以使用自定义的类型了。测试代码如下 package main
import (
"context"
"encoding/json"
"fmt"
"reflect"
"time"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/cloudwego/hertz/pkg/route/param"
"github.com/cloudwego/hertz/pkg/app/server/binding"
)
// 自定义类型
type Mytime time.Time
// 实现 MarshalJSON 方法,用于 JSON 序列化
func (mt Mytime) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Time(mt).Format(time.RFC3339))
}
// 实现 UnmarshalJSON 方法,用于 JSON 反序列化
func (mt *Mytime) UnmarshalJSON(data []byte) error {
var timeStr string
if err := json.Unmarshal(data, &timeStr); err != nil {
return err
}
t, err := time.Parse(time.RFC3339, timeStr)
if err != nil {
return err
}
*mt = Mytime(t)
return nil
}
// 自定义解码函数
func decodeMytime(req *protocol.Request, params param.Params, text string) (reflect.Value, error) {
if text == "" {
return reflect.ValueOf(Mytime(time.Time{})), nil
}
t, err := time.Parse(time.RFC3339, text)
if err != nil {
return reflect.Value{}, err
}
return reflect.ValueOf(Mytime(t)), nil
}
func main() {
// 创建 BindConfig 并注册 Mytime 的自定义解码器
config := binding.NewBindConfig() // 使用 binding.NewBindConfig
config.MustRegTypeUnmarshal(reflect.TypeOf(Mytime{}), decodeMytime)
// 创建 Hertz 服务器,并设置自定义 BindConfig
r := server.New(
server.WithBindConfig(config), // 设置自定义 BindConfig
)
// 注册路由
r.POST("/hello", func(ctx context.Context, c *app.RequestContext) {
// 定义请求结构体
type ReqTime struct {
Birthday Mytime `form:"birth"` // 使用 form 标签
}
// BindAndValidate
var req ReqTime
err := c.BindAndValidate(&req)
if err != nil {
fmt.Println("参数绑定失败:", err)
c.JSON(consts.StatusInternalServerError, utils.H{"message": "参数绑定失败"})
return
}
// 使用绑定和验证后的数据
fmt.Println("Received 'birth':", time.Time(req.Birthday))
c.JSON(consts.StatusOK, utils.H{"message": "成功", "birth": time.Time(req.Birthday)})
})
r.Spin()
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Describe the bug
v0.7.0版本之后 BindAndValidate BindForm不能正确解析时间字符串
To Reproduce
Steps to reproduce the behavior:
type MyTime time.Time
type ReqTime struct {
Birthday MyTime json:"birth" form:"birth" //MyTime已经重写UnmarshalJSON解析字符串
}
func Test(ctx context.Context, c *app.RequestContext) {
var req ReqTime
c.BindAndValidate(&req) // v0.9.0 Birthday是空的。换成v0.6.2就正常了
c.BindForm(&req) // v0.9.0 Birthday也是空的
}
Expected behavior
req.Birthday不应该是空值
Screenshots
Hertz version:
v0.7.0 or above
Environment:
Additional context
The text was updated successfully, but these errors were encountered: