Open cgyy opened 8 years ago
func (form VariantForm) Error(ctx macaron.Context, errs binding.Errors) {}
不是很懂你这个方法是怎么来的。。
你好,是这样的 比如我要自定义form的验证方法,可以这样写:
func (form *MyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
///
}
也可以这样写
func (form MyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
///
}
而自定义错误处理,只能写成这样:
func (cf ContactForm) Error(ctx *macaron.Context, errs binding.Errors) {
// 自定义错误处理过程
}
写成下面这样不起作用
func (cf *ContactForm) Error(ctx *macaron.Context, errs binding.Errors) {
// 自定义错误处理过程不起作用,
}
能否发一下你绑定某个 form(不起作用的) 是怎么写的?
// 商品型号
type VariantForm struct {
OptionValues []int
Price float32 `binding:"Required"`
Sku string
}
// 验证选项值需要全部大于0
func (form *VariantForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
if len(errs) > 0 {
return errs
}
for _, v := range form.OptionValues {
if v == 0 {
errs.Add([]string{"OptionValues"}, "RequiredError", "Required")
break
}
}
return errs
}
func (form *VariantForm) Error(ctx *macaron.Context, errs binding.Errors) {
if len(errs) > 0 {
flash := ctx.GetVal(reflect.TypeOf(&session.Flash{})).Interface().(*session.Flash)
errMsg := fmt.Sprintf("%s: %s", strings.Join(errs[0].FieldNames, ","), errs[0].Message)
flash.Error(errMsg)
ctx.Redirect(fmt.Sprintf("/variants/%d/edit", 30))
}
}
自定义错误处理写成下面可以运行:
func (form VariantForm) Error(ctx *macaron.Context, errs binding.Errors) {
if len(errs) > 0 {
flash := ctx.GetVal(reflect.TypeOf(&session.Flash{})).Interface().(*session.Flash)
errMsg := fmt.Sprintf("%s: %s", strings.Join(errs[0].FieldNames, ","), errs[0].Message)
flash.Error(errMsg)
ctx.Redirect(fmt.Sprintf("/variants/%d/edit", 30))
}
}
额。。其实我想说的是,注册路由部分的代码。。
好的,代码是这样的:
type VariantsController struct {
*macaron.Context
}
func MapVariants(ctx *macaron.Context) {
ctx.Map(&VariantsController{ctx})
}
m.Group("/variants", func() {
m.Get("/:id/edit", (*VariantsController).Edit)
m.Put("/:id", binding.Bind(VariantForm{}), (*VariantsController).Update)
}, MapVariants)
额。。看起来没问题。。我看了代码,判断 Validate 和 Error 的用法是一样的。。暂时不知道为什么。。0 0
似乎是Bind 方法里面没有判断指针类型的原因 binding.go 104行
func Bind(obj interface{}, ifacePtr ...interface{}) macaron.Handler {
return func(ctx *macaron.Context) {
bind(ctx, obj, ifacePtr...)
if handler, ok := obj.(ErrorHandler); ok {
ctx.Invoke(handler.Error)
} else {
ctx.Invoke(errorHandler)
}
}
}
第210行
func Validate(obj interface{}) macaron.Handler {
return func(ctx *macaron.Context) {
var errors Errors
v := reflect.ValueOf(obj)
k := v.Kind()
if k == reflect.Interface || k == reflect.Ptr {
v = v.Elem()
k = v.Kind()
}
if k == reflect.Slice || k == reflect.Array {
for i := 0; i < v.Len(); i++ {
e := v.Index(i).Interface()
errors = validateStruct(errors, e)
if validator, ok := e.(Validator); ok {
errors = validator.Validate(ctx, errors)
}
}
} else {
errors = validateStruct(errors, obj)
if validator, ok := obj.(Validator); ok {
errors = validator.Validate(ctx, errors)
}
}
ctx.Map(errors)
}
}
噢。。那这个目前我还没想到什么好的办法,因为 Bind 是禁止你传指针的,否则会出现大量数据竞争破坏内存出现奇怪的错误
Validate 和Error 对指针的处理方式不统一, 前者接受指针类型而后者不接受
// 这样的方法不被识别 func (form VariantForm) Error(ctx macaron.Context, errs binding.Errors) {}
// macaron 识别这样的方法 func (form VariantForm) Validate(ctx macaron.Context, errs binding.Errors) binding.Errors {}