Golang:验证切片项中的结构字段

Golang: Validate Struct Fields in Slice Items

提问人:samme4life 提问时间:6/16/2022 更新时间:6/7/2023 访问量:4419

问:

我是 Golang 的新手。

Golang版本:1.17.8

验证者:“github.com/go-playground/validator/v10"

我想在加载到嵌套结构数据结构后验证传入的 JSON 有效负载。 这是我传入的 JSON 有效负载,

  {
  "name": "Yomiko",
  "address": {
    "city": "Tokyo",
    "street": "Shibaura St"
  },
  "children":[
    {
      "lastName": "Takayashi"
    }
  ],
  "isEmployed": false
  }

这是我的user.go文件,

package main

type User struct {
    Name    string
    Address *Address `validate:"required"`
    Children []*Child
    IsEmployed *bool `validate:"required"`
}
type Address struct {
    City     string `validate:"required"`
    Street  string `validate:"required"`
}

type Child struct {
    Title string `validate:"required"`
    FirstName string
    LastName string `validate:"required"`
}

这是我的测试函数,

func TestUserPayload(t *testing.T) {
    actualUserPayload := NewUserPayloadFromFile("userpayload.json")

    validate := validator.New()
    err := validate.Struct(actualUserPayload)
    if err != nil {
        t.Error("Validation Error: ", err)
    }

}

此测试通过。但是,我预计它会失败,因为 Child.Title 被标记为必需。我预料到以下错误,

Validation Error:  Key: 'Child.Title' Error:Field validation for 'Title' failed on the 'required' tag

但是,当我循环遍历子级切片并按如下方式验证每个子结构时,测试会按预期失败,

func TestUserPayload(t *testing.T) {
    actualUserPayload := NewUserPayloadFromFile("userpayload.json")

    validate := validator.New()
    err := validate.Struct(actualUserPayload)
    if err != nil {
        t.Error("Validation Error: ", err)
    }

    children := actualUserPayload.Children

    for _, child := range children {
        err := validate.Struct(child)
        if err != nil {
            t.Error("Validation Error: ", err)
        }
    }

}

有没有一种简单的方法可以对结构片中的项目进行这种验证?

JSON 验证 Go 结构 体切片

评论


答:

4赞 phonaputer 6/16/2022 #1

根据验证器包的文档,您可以在 struct 标签中使用来获取此行为。这会导致验证器也验证嵌套的 struct/slice/etc。dive

所以你需要将你的结构更新为:User

type User struct {
    Name       string
    Address    *Address `validate:"required"`
    Children   []*Child `validate:"dive"`
    IsEmployed *bool    `validate:"required"`
}

这是它在 Go Playground 中工作

评论

3赞 blackgreen 6/16/2022
此外,要验证切片字段是否存在验证所有元素,请使用 ,go beforevalidate:"required,dive"requireddive
0赞 sareno 6/7/2023 #2

我正在使用杜松子酒,对我有用:binding:required,dive

type Child struct {
  Name string `json:"name" binding:"required"`
}

type Body struct {
  Children []Child `json:"children" binding:"required,dive"` 👈
}