Skip to content

When the validation field does not exist #1399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
how2j-coder opened this issue Mar 13, 2025 · 3 comments
Open

When the validation field does not exist #1399

how2j-coder opened this issue Mar 13, 2025 · 3 comments
Labels

Comments

@how2j-coder
Copy link

struct

type Request struct {
	Name  string `json:"name" validate:"optional_not_empty"`
	Email string `json:"email"`
}

How Customize one optional_not_empty to achieve the following results?

cases

testCases := []Request{
	{ Email: ""},         // The Name field is not inpassed, and the verification is passed
	{Name: "John", Email: ""},     // Name is passed in and the verification passes
        {Name: "", Email: ""},     // Name is passed in, but the value is blank and the verification fails
}
@nodivbyzero
Copy link
Contributor

Interesting scenario...
I'd love to see solutions from our community!
Personally, I would create a custom validator for this case.

@zemzale
Copy link
Member

zemzale commented Mar 19, 2025

It's possible to do

type Request struct {
	Name  *string `json:"name" validate:"omitempty,gt=0"`
	Email string  `json:"email"`
}

I am not sure if there is any other way how to do it. If you have to separate logic for not exist and null value, sadly with go we can do only this or using something like sql.Null types.

@how2j-coder
Copy link
Author

@nodivbyzero Hello, I can only tell if I have this field in my struct by the address right now, but I don't feel good about that, It's like this

func validateOptionalNotEmpty(fl valid.FieldLevel) bool {
	// Gets the value of the field 获取字段的值
	field := fl.Field()
	if field.Kind() == reflect.Ptr && field.IsNil() {
		return true
	}

	// If the field is passed in, check if its value is empty 如果字段传入了,则检查其值是否为空
	switch field.Kind() {
	case reflect.String:
		return field.String() != ""
	case reflect.Slice, reflect.Map, reflect.Array:
		return field.Len() > 0
	case reflect.Ptr, reflect.Interface:
		return !field.IsNil()
	default:
		return true // Other types pass by default 其他类型默认通过
	}
}
......
func (v *CustomValidator) lazyInit() {
	v.Once.Do(func() {
		v.Validate = valid.New()
		v.Validate.SetTagName("binding")

		// Register a custom validation rule 注册自定义校验规则
		// optional_not_empty - The Null Test field type should be set to the pointer type 空效验 字段类型要设置为指针类型
                // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
		_ = v.Validate.RegisterValidation("optional_not_empty", validateOptionalNotEmpty, true)
	})
}

With RegisterValidation, I can get the Form Struct, which is the Struct I created, but how can I get the JSON data that was passed in for the request?

example:

this is request data:

{
  "role_name": "ordinary",
  "remark": "user role",
  "test": "test filed"
}

this my struct:

type UpdateRoleReq struct {
	RoleName string `json:"role_name" binding:""`
	Remark string `json:"remark" binding:""`
}

got my original request data via validateOptionalNotEmpty:

func validateOptionalNotEmpty(fl valid.FieldLevel, rawData interface{}) bool  {
  	print(rawData)
        // print:
	//	{
	//		"role_name": "ordinary",
	//		"remark": "user role",
	//		"test": "test filed"
	//	}
     

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants