Macaron Documentation
  • Welcome
  • Starter Guide
  • Core Concepts
  • Core Services
  • Custom Services
  • Middlewares
    • Routing
    • Templating
    • Gzip
    • Localization
    • Data Binding and Validation
    • Cache
    • Captcha
    • Session
    • Cross-Site Request Forgery
    • Embed Binary Data
    • Serving Multiple Sites
  • FAQs
  • 简体中文
    • 初学者指南
    • 核心概念
    • 核心服务
    • 自定义服务
    • 中间件和辅助模块
      • 路由模块
      • 模板引擎
      • Gzip 压缩
      • 应用本地化
      • 数据绑定与验证
      • 缓存管理(Cache)
      • 验证码服务
      • 会话管理(Session)
      • 跨域请求攻击(CSRF)
      • 嵌入二进制数据
      • 服务多个站点
    • 常见问题
Powered by GitBook
On this page
  • 下载安装
  • 使用示例
  • 获取表单数据
  • 获取 JSON 数据
  • 绑定到接口
  • 处理器说明
  • Bind
  • Form
  • MultipartForm 和文件上传
  • Json
  • Validate
  • 自定义操作
  • 自定义验证
  • 自定义验证规则
  • 自定义错误处理

Was this helpful?

  1. 简体中文
  2. 中间件和辅助模块

数据绑定与验证

Previous应用本地化Next缓存管理(Cache)

Last updated 5 years ago

Was this helpful?

中间件 binding 为 提供了请求数据绑定与验证的功能。

下载安装

go get github.com/go-macaron/binding

使用示例

获取表单数据

假设您有一个联系人信息的表单,其中姓名和信息为必填字段,则我们可以使用如下结构来进行表示:

type ContactForm struct {
    Name           string `form:"name" binding:"Required"`
    Email          string `form:"email"`
    Message        string `form:"message" binding:"Required"`
    MailingAddress string `form:"mailing_address"`
}

然后通过 Macaron 增加如下路由:

m.Post("/contact/submit", binding.Bind(ContactForm{}), func(contact ContactForm) string {
    return fmt.Sprintf("Name: %s\nEmail: %s\nMessage: %s\nMailing Address: %v",
        contact.Name, contact.Email, contact.Message, contact.MailingAddress)
})

命名约定

默认情况下,form 标签的名称使用以下命名约定:

  • Name -> name

  • UnitPrice -> unit_price

也就是说,上面例子中的结构定义可以简化为如下代码:

type ContactForm struct {
    Name           string `binding:"Required"`
    Email          string
    Message        string `binding:"Required"`
    MailingAddress string
}

超赞!有木有?

获取 JSON 数据

将指定 form 标签的地方替换为 json,就可以完成对 JSON 数据的绑定。

绑定到接口

如果您希望传递接口而不是一个具体的结构,则可以使用如下方法:

m.Post("/contact/submit", binding.Bind(ContactForm{}, (*MyInterface)(nil)), func(contact MyInterface) {
    // ... 您接收到的值为一个接口
})

处理器说明

原则上,每个处理器之间是相互独立的,但在特定情况下,它们之间会相互调用。

Bind

请求处理流程:

  1. 反序列化请求数据到结构

备注:

  • 当使用默认的错误处理机制时,您的应用(队列后方的处理器)将根本不会意识到当前请求的存在。

  • 头信息 Content-Type 是用于决定如何对请求数据进行反序列化的根本条件。

Form

请求处理流程:

  1. 反序列化请求数据到结构

MultipartForm 和文件上传

请求处理流程:

  1. 反序列化请求数据到结构

使用示例

type UploadForm struct {
    Title      string                `form:"title"`
    TextUpload *multipart.FileHeader `form:"txtUpload"`
}

func main() {
    m := macaron.Classic()
    m.Post("/", binding.MultipartForm(UploadForm{}), uploadHandler(uf UploadForm) string {
        file, err := uf.TextUpload.Open()
        // ... 您可以在这里读取上传的文件内容
    })
    m.Run()
}

Json

请求处理流程:

  1. 反序列化请求数据到结构

Validate

验证规则

目前有一些内置的验证规则,通过格式为 binding:"<Name>" 的标签使用。

名称

说明

OmitEmpty

值为空时忽略后续验证

Required

必须为相同类型的非零值

AlphaDash

必须为半角英文字母、阿拉伯数字或 -_

AlphaDashDot

必须为半角英文字母、阿拉伯数字、-_ 或 .

Size(int)

固定长度

MinSize(int)

最小长度

MaxSize(int)

最大长度

Range(int,int)

取值范围(包含边界值)

Email

必须为邮箱地址

Url

必须为 HTTP/HTTPS URL 地址

In(a,b,c,...)

必须为数组的一个元素

NotIn(a,b,c,...)

必须不是数组的元素

Include(string)

必须包含

Exclude(string)

必须不包含

Default(string)

当字段为零值时设置默认值(当使用接口绑定时不能设置该规则)

当需要使用多条规则时: binding:"Required;MinSize(10)"。

自定义操作

自定义验证

func (cf ContactForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
    if strings.Contains(cf.Message, "Go needs generics") {
        errs = append(errors, binding.Error{
            FieldNames:     []string{"message"},
            Classification: "ComplaintError",
            Message:        "Go has generics. They're called interfaces.",
        })
    }
    return errs
}

现在,任何包含信息 "Go needs generics" 的联系人表单都会报错。

自定义验证规则

假设您需要验证字段的最小值:

binding.AddParamRule(&binding.ParamRule{
    IsMatch: func(rule string) bool {
        return strings.HasPrefix(rule, "Min(")
    },
    IsValid: func(errs binding.Errors, rule, name string, v interface{}) (bool, binding.Errors) {
        num, ok := v.(int)
        if !ok {
            return false, errs
        }
        min, _ := strconv.Atoi(rule[4 : len(rule)-1])
        if num < min {
            errs.Add([]string{name}, "MinimumValue", "Value is too small")
            return false, errs
        }
        return true, errs
    },
})
binding.AddRule(&binding.Rule{
    IsMatch: func(rule string) bool {
        return rule == "String"
    },
    IsValid: func(errs binding.Errors, name string, v interface{}) (bool, binding.Errors) {
        _, ok := v.(string)
        return ok, errs
    },
})

自定义规则的应用发生在内置规则之后。

自定义错误处理

func (cf ContactForm) Error(ctx *macaron.Context, errs binding.Errors) {
    // 自定义错误处理过程
}

该操作发生在自定义验证规则被应用之后。

搞定!函数 会帮助您完成对必选字段的数据验证。

默认情况下,如果在验证过程中发生任何错误(例如:必填字段的值为空),binding 中间件就会直接向客户端返回错误信息,提前终止请求的处理。如果您不希望 binding 中间件自动终止请求的处理,则可以使用 函数来忽略对错误的自动处理。

请不要使用类型为指针的嵌入结构,这会导致错误。请查看 上的相关讨论获取完整信息。

如果您想要自定义命名约定,可以通过 函数来设置。该函数接受一个类型为 的值作为参数。

使用 网站工具可以帮助您更好更快地得根据 JSON 数据生成 Go 语言中对应的结构。

函数 是一个便利性的高层封装,它能够自动识别表单类型并完成数据绑定与验证。

通过 函数完成数据验证

如果您的结构实现了 接口,则会调用相应的错误处理方法 ErrorHandler.Error;否则会使用默认的错误处理机制。

请不要尝试绑定指向某个结构的指针,binding 中间件会直接 panic 并退出程序 。

函数 用于反序列化表单数据,可以是查询或 form-urlencoded 类型的请求。

通过 函数完成数据验证

需要注意的是,该函数不具有默认错误处理机制。您可以通过获取类型为 的参数来完成自定义错误处理。

类似 ,函数 同样是反序列化表单数据到结构。除此之外,它还能处理 enctype="multipart/form-data" 类型的 POST 请求。如果结构中包含类型为 (或 []*multipart.FileHeader)的字段,您可以直接从该字段读取客户端上传的文件。

通过 函数完成数据验证

同样的,和函数 一样,该函数不具有默认错误处理机制,但您可以通过获取类型为 的参数来完成自定义错误处理。

函数 反序列化 JSON 数据。

通过 函数完成数据验证

与函数 ,该函数不具有默认错误处理机制,但您可以通过获取类型为 的参数来完成自定义错误处理。

函数 接受一个结构并对它进行基本数据验证。如果该结构实现了 接口,则会调用 Validator.Validate() 方法完成后续的数据验证。

如果您想要进行自定义的附加验证操作,您的结构可以通过实现接口 来完成:

当您觉得内置的验证规则不够时,可以通过函数 来增加自定义验证规则。该函数接受一个类型为 的参数。

如果您的规则非常简单,也可以使用 ,它接受类型为 的参数:

如果您即不想使用默认的错误处理机制,又希望 binding 中间件自动化地调用您的自定义错误处理,则可以通过实现接口 来完成:

binding.Bind
binding.BindIgnErr
martini-contrib/binding issue 30
binding.SetNameMapper
binding.NameMapper
JSON-to-Go
binding.Bind
binding.Validate
binding.ErrorHandler
以防止可能发生的数据竞争
binding.Form
binding.Validate
binding.Errors
binding.Form
binding.MultipartForm
*multipart.FileHeader
binding.Validate
binding.Form
binding.Errors
binding.Json
binding.Validate
binding.Form
binding.Errors
binding.Validate
binding.Validator
binding.Validator
binding.AddParamRule
binding.ParamRule
binding.AddRule
binding.Rule
binding.ErrorHandler
GitHub
API 文档
Macaron 实例