# 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:
Required
not 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.Alpha
alpha characters. Valid type isstring
, all other types are invalid.Numeric
numerics. Valid type isstring
, all other types are invalid.AlphaNumeric
alpha 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)AlphaDash
alpha characters or numerics or-_
. Valid type isstring
, all other types are invalid.Email
Email address. Valid type isstring
, all other types are invalid.IP
IP address,Only support IPv4 address. Valid type isstring
, all other types are invalid.Base64
base64 encoding. Valid type isstring
, all other types are invalid.Mobile
mobile number. Valid type isstring
, all other types are invalid.Tel
telephone number. Valid type isstring
, all other types are invalid.Phone
mobile number or telephone number. Valid type isstring
, all other types are invalid.ZipCode
zip 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 →