Go “go-playground/validator/v10”: 如何注册自定义错误消息

huangapple go评论91阅读模式
英文:

Go "go-playground/validator/v10": how to register a custom error message

问题

我使用github.com/go-playground/validator/v10

我创建了一个自定义验证器(stringMinLength),用于验证字符串的长度是否大于给定的长度。如果要验证的字符串长度小于允许的最小长度,则我希望设置一个描述问题的错误消息。

以下是我的代码:

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
	"strconv"
	"unicode/utf8"
)

type Profile struct {
	Name string `validate:"required,stringMinLength=3"`
	Age  uint   `validate:"required,gt=10"`
}

// 参见 https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Custom_Validation_Functions
func stringMinLength(inField validator.FieldLevel) bool {
	//var value string = inField.Field().String()
	value, kind, nullable := inField.ExtractType(inField.Field())
	param := inField.Param()

	fmt.Printf("=> name: [%s]\n", inField.FieldName())
	fmt.Printf("=> tag: [%s]\n", inField.GetTag())
	fmt.Printf("=> struct field name: [%s]\n", inField.StructFieldName())
	fmt.Printf("=> param: [%s]\n", param)
	fmt.Printf("=> value: [%s]\n", value.String())
	fmt.Printf("=> kind: [%s]\n", kind.String())
	if nullable {
		fmt.Printf("=> nullable: true\n")
	} else {
		fmt.Printf("=> nullable: false\n")
	}

	// 参数必须是一个整数!
	minLength, err := strconv.ParseUint(param, 10, 32)
	if err != nil {
		panic(fmt.Sprintf(`stringMinLength parameter must be an unsigned integer! (got "%s" instead)`, param))
	}

	status := uint64(utf8.RuneCountInString(value.String())) >= minLength
	if !status {
		// 我想注册一个错误消息,告诉调用者给定的名称太短了
	}

	return status
}

func main() {

	myValidator := validator.New()
	if err := myValidator.RegisterValidation("stringMinLength", stringMinLength); err != nil {
		panic(err)
	}

	// ===================================================
	// 测试成功
	// ===================================================

	profile := Profile{
		Name: "Joe",
		Age:  25,
	}

	if err := myValidator.Struct(profile); err != nil {
		panic(err)
	}

	fmt.Printf("SUCCESS (as expected) => OK\n")

	// ===================================================
	// 测试失败
	// ===================================================

	profile = Profile{
		Name: "IT",
		Age:  9,
	}

	if err := myValidator.Struct(profile); err != nil {
		fmt.Printf("FAILURE (as expected) => OK\n")

		fmt.Printf("err: %T\n", err) // => validator.ValidationErrors
		errors := err.(validator.ValidationErrors)
		for _, v := range errors {
			fmt.Printf("%s\n", v.Error())
		}
	}
}

你可以在这里进行测试:https://go.dev/play/p/Ol6sq8hAyjq

问题: 我如何从我的自定义验证器(stringMinLength)返回错误消息?

我已经阅读了关于“翻译器”的信息,但我不明白翻译器如何解决这个问题。

英文:

I use github.com/go-playground/validator/v10.

I create a custom validator (stringMinLength) that verifies that a string is longer than a given length. If the length of the string to validate is shorter than the given minimum allowed length, then I want to set an error message that describes the problem.

Below, my code:

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
	"strconv"
	"unicode/utf8"
)

type Profile struct {
	Name string `validate:"required,stringMinLength=3"`
	Age  uint   `validate:"required,gt=10"`
}

// See https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Custom_Validation_Functions
func stringMinLength(inField validator.FieldLevel) bool {
	//var value string = inField.Field().String()
	value, kind, nullable := inField.ExtractType(inField.Field())
	param := inField.Param()

	fmt.Printf("=> name: [%s]\n", inField.FieldName())
	fmt.Printf("=> tag: [%s]\n", inField.GetTag())
	fmt.Printf("=> struct field name: [%s]\n", inField.StructFieldName())
	fmt.Printf("=> param: [%s]\n", param)
	fmt.Printf("=> value: [%s]\n", value.String())
	fmt.Printf("=> kind: [%s]\n", kind.String())
	if nullable {
		fmt.Printf("=> nullable: true\n")
	} else {
		fmt.Printf("=> nullable: false\n")
	}

	// The parameter must be an integer!
	minLength, err := strconv.ParseUint(param, 10, 32)
	if err != nil {
		panic(fmt.Sprintf(`stringMinLength parameter must be an unsigned integer! (got "%s" instead)`, param))
	}

	status := uint64(utf8.RuneCountInString(value.String())) >= minLength
	if !status {
		// I want to register an error message that informs the caller that the given name is too short
	}

	return status
}

func main() {

	myValidator := validator.New()
	if err := myValidator.RegisterValidation("stringMinLength", stringMinLength); err != nil {
		panic(err)
	}

	// ===================================================
	// Test SUCCESS
	// ===================================================

	profile := Profile{
		Name: "Joe",
		Age:  25,
	}

	if err := myValidator.Struct(profile); err != nil {
		panic(err)
	}

	fmt.Printf("SUCCESS (as expected) => OK\n")

	// ===================================================
	// Test FAILURE
	// ===================================================

	profile = Profile{
		Name: "IT",
		Age:  9,
	}

	if err := myValidator.Struct(profile); err != nil {
		fmt.Printf("FAILURE (as expected) => OK\n")

		fmt.Printf("err: %T\n", err) // => validator.ValidationErrors
		errors := err.(validator.ValidationErrors)
		for _, v := range errors {
			fmt.Printf("%s\n", v.Error())
		}
	}
}

You can test it here: https://go.dev/play/p/Ol6sq8hAyjq

Question: how do I return an error message from my custom validator (stringMinLength) ?

I have read information about "translators," but I don't see how translators fit into the problem.

答案1

得分: 1

目前似乎无法实现我需要做的事情:

https://github.com/go-playground/validator/issues/669

该功能将在版本11中添加:

https://github.com/go-playground/validator/issues?q=is%3Aissue+is%3Aopen+label%3Av11

英文:

It seems that what I need to do is not possible right now:

https://github.com/go-playground/validator/issues/669

The functionality will be added to version 11:

https://github.com/go-playground/validator/issues?q=is%3Aissue+is%3Aopen+label%3Av11

huangapple
  • 本文由 发表于 2023年4月3日 21:54:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75920253.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定