如何在Golang中使用ozzo验证执行条件必需验证?

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

How to perform conditional required validation ussing ozzo validation in golang?

问题

在Golang的ozzo-validation中,如何验证一个字段依赖于另一个字段?

例如,如果我有以下代码:

return validation.ValidateStruct(&c,
    validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
    validation.Field(&c.Gender, validation.In("Female", "Male")),
    validation.Field(&c.Email, is.Email),
    validation.Field(&c.Address),
)

如何添加一个验证规则,即只有在Email字段不为空时,Address字段才是必需的?

英文:

In Golang ozzo-validation, how can I validate a field which is dependent on another field ?

For example, if I have the following:

> return validation.ValidateStruct(&c,
> validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
>
> validation.Field(&c.Gender, validation.In("Female", "Male")),
>
> validation.Field(&c.Email, is.Email),
>
> validation.Field(&c.Address),

How can I add a validation that the Address is required only if email is not empty?

答案1

得分: 5

你可以通过两种方式实现:

  • 添加自定义规则
  • 根据前提条件值有条件地添加FieldRules,即在创建字段规则时检查Email,然后将其提供给validation.ValidateStruct

例如:

type Sample struct {
    Name    string
    Gender  string
    Email   string
    Address Address
}

type Address struct {
    // ... 字段
}

func (s Sample) Validate() error {
    var fieldRules []*validation.FieldRules

    fieldRules = append(fieldRules, validation.Field(&s.Name, validation.Required, validation.Length(5, 20)))
    fieldRules = append(fieldRules, validation.Field(&s.Gender, validation.In("Female", "Male")))
    fieldRules = append(fieldRules, validation.Field(&s.Email, is.Email))

    if len(strings.TrimSpace(s.Email)) > 0 {
        fieldRules = append(fieldRules, validation.Field(&s.Address, validation.Required))
        fieldRules = append(fieldRules, validation.Field(&s.Address))
    }

    return validation.ValidateStruct(&s, fieldRules...)
}
英文:

You can achieve it in two ways-

  • <s>Adding your own custom rules</s>
  • Conditionally add FieldRules based on precondition-value i.e check Email while creating field rules then supply it to validation.ValidateStruct

For e.g.:

type Sample struct {
	Name    string
	Gender  string
	Email   string
	Address Address
}

type Address struct {
	// ... fields
}

func (s Sample) Validate() error {
	var fieldRules []*validation.FieldRules

	fieldRules = append(fieldRules, validation.Field(&amp;s.Name, validation.Required, validation.Length(5, 20)))
	fieldRules = append(fieldRules, validation.Field(&amp;s.Gender, validation.In(&quot;Female&quot;, &quot;Male&quot;)))
	fieldRules = append(fieldRules, validation.Field(&amp;s.Email, is.Email))

	if len(strings.TrimSpace(s.Email)) &gt; 0 {
		fieldRules = append(fieldRules, validation.Field(&amp;s.Address, validation.Required))
		fieldRules = append(fieldRules, validation.Field(&amp;s.Address))
	}

	return validation.ValidateStruct(&amp;s, fieldRules...)
}

答案2

得分: 3

该库现在通过validation.When函数支持条件验证。

以下是适合您描述的验证的代码片段。

package main

import (
        "fmt"

        validation "github.com/go-ozzo/ozzo-validation" // 或者如果找不到"When",可以使用"github.com/go-ozzo/ozzo-validation/v4"
)

type Entry struct {
        Name    string
        Gender  string
        Email   string
        Address string
}

func main() {
        v := func(e Entry) {
                fmt.Println(validation.ValidateStruct(&e,
                        validation.Field(&e.Name, validation.Required, validation.Length(5, 20)),

                        // 注意,如果gender是""且不是必需的,验证将不会返回错误。
                        validation.Field(&e.Gender, validation.Required, validation.In("Female", "Male")),

                        validation.Field(&e.Address, validation.When(e.Email != "", validation.Required.Error("Address is required if Email is set"))),
                ))
        }

        // 没有Email时一切正常。
        e := Entry{
                Name:   "My name is!",
                Gender: "Male",
        }
        v(e)

        // Email存在但没有Address时验证失败。
        e = Entry{
                Name:   "My name is!",
                Gender: "Male",
                Email:  "a@org.com",
        }
        v(e)
}

它的输出是:

<nil>
Address: Address is required if Email is set.

该库的文档也对此进行了描述:https://github.com/go-ozzo/ozzo-validation#conditional-validation

英文:

The library now supports conditional validation by the validation.When function.

Here is a code snipped which fits the validation you described.

package main

import (
        &quot;fmt&quot;

        validation &quot;github.com/go-ozzo/ozzo-validation&quot; // or &quot;github.com/go-ozzo/ozzo-validation/v4&quot; if &quot;When&quot; not found
)

type Entry struct {
        Name    string
        Gender  string
        Email   string
        Address string
}

func main() {
        v := func(e Entry) {
                fmt.Println(validation.ValidateStruct(&amp;e,
                        validation.Field(&amp;e.Name, validation.Required, validation.Length(5, 20)),

                        // Note that if gender is &quot;&quot; and not required, validation returns no error.
                        validation.Field(&amp;e.Gender, validation.Required, validation.In(&quot;Female&quot;, &quot;Male&quot;)),

                        validation.Field(&amp;e.Address, validation.When(e.Email != &quot;&quot;, validation.Required.Error(&quot;Address is required if Email is set&quot;))),
                ))
        }

        // All is fine for no Email.
        e := Entry{
                Name:   &quot;My name is!&quot;,
                Gender: &quot;Male&quot;,
        }
        v(e)

        // Validation fails for Email and no Address.
        e = Entry{
                Name:   &quot;My name is!&quot;,
                Gender: &quot;Male&quot;,
                Email:  &quot;a@org.com&quot;,
        }
        v(e)
}

It outputs.

&lt;nil&gt;
Address: Address is required if Email is set.

The library documentation describes it as well: https://github.com/go-ozzo/ozzo-validation#conditional-validation

huangapple
  • 本文由 发表于 2017年7月6日 09:52:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/44938584.html
匿名

发表评论

匿名网友

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

确定