cloudwego / hertz

Go HTTP framework with high-performance and strong-extensibility for building micro-services.
https://www.cloudwego.io
Apache License 2.0
5.04k stars 491 forks source link

BindAndValidate BindForm解析时间字符串为空 #1123

Open wujianbo00 opened 2 months ago

wujianbo00 commented 2 months ago

Describe the bug

v0.7.0版本之后 BindAndValidate BindForm不能正确解析时间字符串

To Reproduce

Steps to reproduce the behavior:

  1. 代码片段 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也是空的 }
  2. 请求curl -X 'POST' 'http://localhost:8080/test' -H 'accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' -d 'birth=2024-01-01%2012%3A00%3A00'

Expected behavior req.Birthday不应该是空值

Screenshots

Hertz version: v0.7.0 or above

Environment:

Additional context

FGYFFFF commented 2 months ago

现在先用json 来规避吧

FGYFFFF commented 2 months ago

我测试了下,如果你的 "MyTime已经重写UnmarshalJSON解析字符串" 是会正常进行参数绑定的;如果你稳定复现的话,可以粘贴一个具体的单测例子。 以下是我的测试 case

type MyTime time.Time

func (m *MyTime) UnmarshalJSON(b []byte) error {
    t := time.Now().AddDate(0, 0, -2)
    *m = MyTime(t)
    return nil
}

type ReqTime struct {
    Birthday MyTime `json:"birth" form:"birth"` //MyTime已经重写UnmarshalJSON解析字符串
}

func TestTime(t *testing.T) {

    r := protocol.NewRequest("POST", "/foo", nil)
    now := time.Now().UTC()
    fmt.Println(now.String())
    r.SetRequestURI(fmt.Sprintf("/foo"))
    r.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))
    kv := url.Values{}
    kv.Set("birth", now.String())
    r.SetBody([]byte(kv.Encode()))

    var req ReqTime
    err := DefaultBinder().Bind(r, &req, nil)
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
        return
    }
}