gorm 结构体中 binding 和 msg 结构体标签

bindingmsg 是结构体标签(struct tags),主要用于数据验证和错误信息提示。它们通常与 Gin 框架的 ShouldBindJSON 配合使用,以及用于处理表单验证。

下面详细解释:

  1. 基本用法示例:
type LoginForm struct {
    Username string `json:"username" binding:"required" msg:"用户名不能为空"`
    Password string `json:"password" binding:"required,min=6" msg:"密码不能为空且长度至少6位"`
    Age      int    `json:"age" binding:"required,gte=18" msg:"年龄必须大于或等于18岁"`
    Email    string `json:"email" binding:"required,email" msg:"请输入有效的邮箱地址"`
}
  1. 在 Gin 中使用:
func Login(c *gin.Context) {
    var form LoginForm
    if err := c.ShouldBindJSON(&form); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
    // 处理登录逻辑...
}
  1. 常用的 binding 验证规则:
type User struct {
    // required: 必填
    Name string `binding:"required"`
    
    // min,max: 字符串长度或数字范围
    Password string `binding:"min=6,max=20"`
    
    // email: 邮箱格式
    Email string `binding:"email"`
    
    // oneof: 枚举值
    Role string `binding:"oneof=admin user guest"`
    
    // gte,lte: 大于等于,小于等于
    Age int `binding:"gte=18,lte=100"`
    
    // url: URL格式
    Website string `binding:"url"`
    
    // 正则表达式
    Phone string `binding:"required,regexp=^1[3-9]\\d{9}$"`
}
  1. 自定义验证器:
type RegisterForm struct {
    Password string `binding:"required,CustomPassword"`
    Phone    string `binding:"required,CustomPhone"`
}

func customValidator() {
    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        // 注册自定义验证器
        v.RegisterValidation("CustomPassword", ValidatePassword)
        v.RegisterValidation("CustomPhone", ValidatePhone)
    }
}

func ValidatePassword(fl validator.FieldLevel) bool {
    password := fl.Field().String()
    // 自定义密码验证逻辑
    return len(password) >= 8
}
  1. 使用 msg 标签自定义错误信息:
type CreateUserForm struct {
    Username string `json:"username" binding:"required" msg:"用户名不能为空"`
    Password string `json:"password" binding:"required,min=6" msg:"密码长度最少6位"`
}

// 处理错误信息的辅助函数
func getValidMsg(err error, obj interface{}) string {
    // 通过反射获取 struct 类型
    getObj := reflect.TypeOf(obj)
    
    // 如果是指针,则获取其基础类型
    if getObj.Kind() == reflect.Ptr {
        getObj = getObj.Elem()
    }
    
    // 将错误信息转换为验证器错误
    if errs, ok := err.(validator.ValidationErrors); ok {
        // 遍历每一个错误
        for _, e := range errs {
            // 获取对应字段
            if f, exist := getObj.FieldByName(e.Field()); exist {
                // 获取 msg 标签内容
                msg := f.Tag.Get("msg")
                if msg != "" {
                    return msg
                }
            }
        }
    }
    
    return err.Error()
}
  1. 在控制器中使用:
func CreateUser(c *gin.Context) {
    var form CreateUserForm
    if err := c.ShouldBindJSON(&form); err != nil {
        // 获取自定义错误信息
        errMsg := getValidMsg(err, form)
        c.JSON(400, gin.H{"error": errMsg})
        return
    }
    
    // 处理业务逻辑...
}
  1. 组合验证规则:
type Product struct {
    // 多个验证规则用逗号分隔
    Name  string `binding:"required,min=2,max=50" msg:"产品名称长度必须在2-50之间"`
    Price float64 `binding:"required,gte=0" msg:"价格必须大于或等于0"`
    // 条件验证:当 Status 为 "active" 时,Description 必填
    Status      string `binding:"required,oneof=active inactive" msg:"状态必须是 active 或 inactive"`
    Description string `binding:"required_if=Status active" msg:"当状态为active时,描述必填"`
}
  1. 跨字段验证:
type ChangePassword struct {
    Password        string `binding:"required" msg:"密码不能为空"`
    ConfirmPassword string `binding:"required,eqfield=Password" msg:"两次输入的密码不一致"`
}
  1. 初始化验证器:
func InitValidator() {
    // 注册验证器
    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        // 注册自定义验证器
        v.RegisterValidation("custom_validation", CustomValidationFunc)
        
        // 注册自定义错误信息翻译器
        zhTranslations.RegisterDefaultTranslations(v, trans)
    }
}

这些标签主要用于:

  • 数据验证(binding)
  • 自定义错误信息(msg)
  • 参数绑定
  • 表单验证
  • API 接口参数验证

通过合理使用这些标签,可以:

  • 减少手动编写验证代码
  • 提供更友好的错误提示
  • 确保数据的完整性和有效性
  • 提高代码的可维护性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值