go 中跨域自定义验证的问题

问题描述 投票:0回答:1

我正在尝试学习 golang 自定义验证,但遇到了很多麻烦。这是我一直在尝试的代码:

package main
import (
        "reflect"
        "github.com/go-playground/validator/v10"
        "fmt"
)
type TeamMember struct {
        Country string
        Age int
        DropShip bool `validate:"is_eligible"`
}
func CustomValidation(fl validator.FieldLevel) bool {
  /*
    if(DropShip == true) {
       httpresponse = curl https://3rd-party-api.com/?country=<Country>&age=<Age>
       return httpresponse.code == 200
    }
    return false
  */

  b := fl.Parent()
  fmt.Println(reflect.TypeOf(b))
  fmt.Println(reflect.ValueOf(b))
  c := reflect.ValueOf(b).Interface()
  fmt.Println(c.(TeamMember))
  fmt.Println("============")
  return true
}


func main() {
  var validate *validator.Validate
  validate = validator.New(validator.WithRequiredStructEnabled())
  _ = validate.RegisterValidation("is_eligible", CustomValidation)
  teammember := TeamMember{"Canada", 34, true}

  validate.Struct(teammember)
}

您可以在代码注释中看到我尝试的验证逻辑...如果

DropShip
字段为 true,那么我需要将
Country
Age
提交到另一个 API 以查看该团队成员是否符合资格。

问题是我正在努力使用

reflect
库来访问
Country
结构中的
Age
TeamMember
字段。
fmt.Println(c.(TeamMember))
行使我的程序崩溃。

有人可以给我一个如何访问其他 TeamMember 字段的示例吗?或者我的验证方法是否违反了 golang 中验证的惯用方式?

go validation reflection
1个回答
0
投票

在这种情况下,最好使用自定义结构级别验证:

package main

import (
    "fmt"

    "github.com/go-playground/validator/v10"
)

type TeamMember struct {
    Country  string
    Age      int
    DropShip bool
}

func TeamMemberStructLevelValidation(sl validator.StructLevel) {
    teamMember := sl.Current().Interface().(TeamMember)

    if teamMember.DropShip {
        // submit the Country and Age to another API to see if this team member is eligible.
        if teamMember.Country == "Canada" && teamMember.Age == 34 {
            sl.ReportError(teamMember.Country, "country", "Country", "is_eligible", "")
            sl.ReportError(teamMember.Age, "age", "Age", "is_eligible", "")
        }
    }
}

func main() {
    validate := validator.New(validator.WithRequiredStructEnabled())
    validate.RegisterStructValidation(TeamMemberStructLevelValidation, TeamMember{})

    teamMember := TeamMember{"Canada", 34, true}
    err := validate.Struct(teamMember)

    fmt.Printf("%+v\n", err)
    // Output:
    //   Key: 'TeamMember.country' Error:Field validation for 'country' failed on the 'is_eligible' tag
    //   Key: 'TeamMember.age' Error:Field validation for 'age' failed on the 'is_eligible' tag
}

另请参阅包提供的示例:https://github.com/go-playground/validator/blob/v10.15.3/_examples/struct-level/main.go

© www.soinside.com 2019 - 2024. All rights reserved.