post FormData time is error. invalid character '-' after top-level value

post map is ok.

// User
type User struct {
    ID  int64   `json:"id" form:"id" gorm:"column:id;primary_key;AUTO_INCREMENT;comment:'ID'"`
    Birthday DateType   `form:"birthday" json:"birthday" gorm:"column:birthday;type:DATE;not null;default:'1990-01-10';comment:'birthday'"`
}
type DateType time.Time

func (dt DateType) MarshalText() ([]byte, error) {
    fmt.Println("DateType", "MarshalText")
    t := time.Time(dt)
    value := t.Format("2006.01.02")
    return []byte(fmt.Sprintf(`%s`, value)), nil
}

func (dt DateType) MarshalJSON() ([]byte, error) {
    fmt.Println("DateType", "MarshalJSON")
    t := time.Time(dt)
    var stamp = fmt.Sprintf(`"%s"`, t.Format("2006.01.02"))
    return []byte(stamp), nil
}

var _ json.Unmarshaler = &DateType{}

func (dt *DateType) UnmarshalJSON(bs []byte) error {
    var s string
    err := json.Unmarshal(bs, &s)
    if err != nil {
        return err
    }
    t, err := time.ParseInLocation("2006.01.02", s, time.UTC)
    if err != nil {
        return err
    }
    *dt = DateType(t)
    return nil
}

func UserUpdate(c *gin.Context) {
    data := new(model.User)
    fmt.Println("birthday|"+c.PostForm("birthday")+"|")
    err := c.ShouldBind(&data)
    if err != nil {
         //  post FormData err
        fmt.Println("ShouldBind", err)
        return
    }
    // post map is ok.
    fmt.Println("OK", data)
    return
}

What's the reason?

Comment From: githubzhaoqian

type UserTemp struct {
    ID  int64   `json:"id" form:"id" gorm:"column:id;primary_key;AUTO_INCREMENT;comment:'ID'"`
    Birthday string   `form:"birthday" json:"birthday" gorm:"column:birthday;type:DATE;not null;default:'1990-01-10';comment:'birthday'"`
}

post FormData. This also circumvented the error.

Comment From: githubzhaoqian

// FormData

id: 1
state: 2
uname: IM
detail: 
birthday: 2002-07-17
gender: 2
avatar_file: (binary)

Comment From: crodwell

I have the same problem, wondering what's causing it! Posting JSON forms works but using the form tag and using a multipart form is no good

Comment From: viet-wego

Hi @githubzhaoqian, Did you manage to solve this? I got the same problem with form tag & query parameter, json works just fine.

Comment From: chokoboko

Hi all, I had the same problem and solved it by wrapping the []byte result from MarshalJSON with double quote chars ("). One way to do it is with fmt.Sprintf("%q", ..), in your case:

func (dt DateType) MarshalJSON() ([]byte, error) {
    t := time.Time(dt)
    stamp := []byte(fmt.Sprintf("%q", t.Format("2006-01-02")))
    return stamp, nil
}

Comment From: JCBOSH

const TimeFormat = "2006-01-02 15:04:05"
func (dt DateType) MarshalJSON() ([]byte, error) {
    if time.Time(dt).IsZero() {
        return []byte("\"\""), nil
    }
    b := make([]byte, 0, len(TimeFormat)+2)
    b = append(b, '"')
    b = time.Time(dt).AppendFormat(b, TimeFormat)
    b = append(b, '"')
    return b, nil
}

The above is my MarshalJSON code, which has the same effect, but the result is still an error. Of course, I have also tried your code, but it has not worked. May I ask how you specifically resolved it? Could you please provide a specific example that includes the request?