# Form validation
The Form validation module is used for data validation and error collection.
# Localization
In order to localize validation error messages, one might use SetDefaultMessage function of the validation package.
Note that format markers (%d, %s) must be preserved in translated text to provide resulting messages with validation context values.
Default template messages are present in validation.MessageTmpls variable.
Simple message localization for Russian language:
import "github.com/beego/beego/v2/core/validation"
func init() {
validation.SetDefaultMessage(map[string]string{
"Required": "Должно быть заполнено",
"Min": "Минимально допустимое значение %d",
"Max": "Максимально допустимое значение %d",
"Range": "Должно быть в диапазоне от %d до %d",
"MinSize": "Минимально допустимая длина %d",
"MaxSize": "Максимально допустимая длина %d",
"Length": "Длина должна быть равна %d",
"Alpha": "Должно состоять из букв",
"Numeric": "Должно состоять из цифр",
"AlphaNumeric": "Должно состоять из букв или цифр",
"Match": "Должно совпадать с %s",
"NoMatch": "Не должно совпадать с %s",
"AlphaDash": "Должно состоять из букв, цифр или символов (-_)",
"Email": "Должно быть в правильном формате email",
"IP": "Должен быть правильный IP адрес",
"Base64": "Должно быть представлено в правильном формате base64",
"Mobile": "Должно быть правильным номером мобильного телефона",
"Tel": "Должно быть правильным номером телефона",
"Phone": "Должно быть правильным номером телефона или мобильного телефона",
"ZipCode": "Должно быть правильным почтовым индексом",
})
}
# Examples:
Direct use:
import (
"github.com/beego/beego/v2/core/validation"
"log"
)
type User struct {
Name string
Age int
}
func main() {
u := User{"man", 40}
valid := validation.Validation{}
valid.Required(u.Name, "name")
valid.MaxSize(u.Name, 15, "nameMax")
valid.Range(u.Age, 0, 18, "age")
if valid.HasErrors() {
// If there are error messages it means the validation didn't pass
// Print error message
for _, err := range valid.Errors {
log.Println(err.Key, err.Message)
}
}
// or use like this
if v := valid.Max(u.Age, 140, "age"); !v.Ok {
log.Println(v.Error.Key, v.Error.Message)
}
// Customize error messages
minAge := 18
valid.Min(u.Age, minAge, "age").Message("18+ only!!")
// Format error messages
valid.Min(u.Age, minAge, "age").Message("%d+", minAge)
}
Use through StructTag
import (
"log"
"strings"
"github.com/beego/beego/v2/core/validation"
)
// Set validation function in "valid" tag
// Use ";" as the separator of multiple functions. Spaces accept after ";"
// Wrap parameters with "()" and separate parameter with ",". Spaces accept after ","
// Wrap regex match with "//"
//
type user struct {
Id int
Name string `valid:"Required;Match(/^Bee.*/)"` // Name can't be empty or start with Bee
Age int `valid:"Range(1, 140)"` // 1 <= Age <= 140, only valid in this range
Email string `valid:"Email; MaxSize(100)"` // Need to be a valid Email address and no more than 100 characters.
Mobile string `valid:"Mobile"` // Must be a valid mobile number
IP string `valid:"IP"` // Must be a valid IPv4 address
}
// If your struct implemented interface `validation.ValidFormer`
// When all tests in StructTag succeed, it will execute Valid function for custom validation
func (u *user) Valid(v *validation.Validation) {
if strings.Index(u.Name, "admin") != -1 {
// Set error messages of Name by SetError and HasErrors will return true
v.SetError("Name", "Can't contain 'admin' in Name")
}
}
func main() {
valid := validation.Validation{}
u := user{Name: "Beego", Age: 2, Email: "[email protected]"}
b, err := valid.Valid(&u)
if err != nil {
// handle error
}
if !b {
// validation does not pass
// blabla...
for _, err := range valid.Errors {
log.Println(err.Key, err.Message)
}
}
}
Available validation functions in StrucTag:
Requirednot empty. :TODO 不为空,即各个类型要求不为其零值Min(min int)minimum value. Valid type isint, all other types are invalid.Max(max int)maximum value. Valid type isint, all other types are invalid.Range(min, max int)Value range. Valid type isint, all other types are invalid.MinSize(min int)minimum length. Valid type isstring slice, all other types are invalid.MaxSize(max int)maximum length. Valid type isstring slice, all other types are invalid.Length(length int)fixed length. Valid type isstring slice, all other types are invalid.Alphaalpha characters. Valid type isstring, all other types are invalid.Numericnumerics. Valid type isstring, all other types are invalid.AlphaNumericalpha characters or numerics. Valid type isstring, all other types are invalid.Match(pattern string)regex matching. Valid type isstring, all other types will be cast to string then match. (fmt.Sprintf("%v", obj).Match)AlphaDashalpha characters or numerics or-_. Valid type isstring, all other types are invalid.EmailEmail address. Valid type isstring, all other types are invalid.IPIP address,Only support IPv4 address. Valid type isstring, all other types are invalid.Base64base64 encoding. Valid type isstring, all other types are invalid.Mobilemobile number. Valid type isstring, all other types are invalid.Teltelephone number. Valid type isstring, all other types are invalid.Phonemobile number or telephone number. Valid type isstring, all other types are invalid.ZipCodezip code. Valid type isstring, all other types are invalid.
# Using label
Sometimes you don't want to use the field name in error message, so that you can use the label tag.
Here is the simple example:
type User struct {
Age int `valid:"Required;Range(1, 140)" label:"age"`
}
And then the output error message is: "age Range is 1 to 140".
# Custom validation
You can register your own validator via calling AddCustomFunc:
type user struct {
// ...
Address string `valid:"ChinaAddress"`
}
func main() {
_ = validation.AddCustomFunc("ChinaAddress", func(v *validation.Validation, obj interface{}, key string) {
addr, ok := obj.(string)
if !ok {
return
}
if !strings.HasPrefix(addr, "China") {
v.AddError(key, "China address only")
}
})
// ...
}
← Log Module Task →